1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
|
export const eq =
<T>(a: T) =>
(b: T): boolean =>
a === b
type TagValue<T, N> = T extends Tag<N, infer V> ? V : never
export const match =
<R, T extends Tag<string, any>>(pattern: {
[key in T['tag'] | '_']?: (v: TagValue<T, key>) => R
}) =>
(tag: T): R =>
(pattern[tag.tag] || (pattern._ as any))(tag.value)
type Tag<N, V> = { tag: N; value: V }
export type Union<T> = { [N in keyof T]: Tag<N, T[N]> }[keyof T]
export const constructors = <T extends Tag<string, any>>(): {
[N in T['tag']]: TagValue<T, N> extends null|never
? (value?: null | never) => T
: (value: TagValue<T, N>) => T
} =>
new Proxy(
{},
{
get(_, k) {
return (value: any) => ({ tag: k, value })
},
},
) as any
export const jlog = (x: any) => console.log(JSON.stringify(x, null, 2))
|