forked from gcanti/io-ts
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathFreeSemigroup.ts
75 lines (68 loc) · 1.57 KB
/
FreeSemigroup.ts
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
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
/**
* **This module is experimental**
*
* Experimental features are published in order to get early feedback from the community, see these tracking
* [issues](https://github.com/gcanti/io-ts/issues?q=label%3Av2.2+) for further discussions and enhancements.
*
* A feature tagged as _Experimental_ is in a high state of flux, you're at risk of it changing without notice.
*
* @since 2.2.7
*/
import { Semigroup } from 'fp-ts/lib/Semigroup'
/**
* @category model
* @since 2.2.7
*/
export interface Of<A> {
readonly _tag: 'Of'
readonly value: A
}
/**
* @category model
* @since 2.2.7
*/
export interface Concat<A> {
readonly _tag: 'Concat'
readonly left: FreeSemigroup<A>
readonly right: FreeSemigroup<A>
}
/**
* @category model
* @since 2.2.7
*/
export type FreeSemigroup<A> = Of<A> | Concat<A>
/**
* @category constructors
* @since 2.2.7
*/
export const of = <A>(a: A): FreeSemigroup<A> => ({ _tag: 'Of', value: a })
/**
* @category constructors
* @since 2.2.7
*/
export const concat = <A>(left: FreeSemigroup<A>, right: FreeSemigroup<A>): FreeSemigroup<A> => ({
_tag: 'Concat',
left,
right
})
/**
* @category destructors
* @since 2.2.7
*/
export const fold = <A, R>(onOf: (value: A) => R, onConcat: (left: FreeSemigroup<A>, right: FreeSemigroup<A>) => R) => (
f: FreeSemigroup<A>
): R => {
switch (f._tag) {
case 'Of':
return onOf(f.value)
case 'Concat':
return onConcat(f.left, f.right)
}
}
/**
* @category instances
* @since 2.2.7
*/
export function getSemigroup<A = never>(): Semigroup<FreeSemigroup<A>> {
return { concat }
}