forked from baetheus/fun
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsync.ts
More file actions
60 lines (46 loc) · 1.57 KB
/
sync.ts
File metadata and controls
60 lines (46 loc) · 1.57 KB
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
import type { $, Kind, Out } from "./kind.ts";
import type { Applicative } from "./applicative.ts";
import type { Extend } from "./extend.ts";
import type { Monad } from "./monad.ts";
import type { Traversable } from "./traversable.ts";
import { constant, flow, pipe } from "./fn.ts";
export type Sync<A> = () => A;
export interface KindSync extends Kind {
readonly kind: Sync<Out<this, 0>>;
}
export function of<A>(a: A): Sync<A> {
return constant(a);
}
export function ap<A>(ua: Sync<A>): <I>(ta: Sync<(a: A) => I>) => Sync<I> {
return (ufai) => flow(ua, ufai());
}
export function map<A, I>(fai: (a: A) => I): (ta: Sync<A>) => Sync<I> {
return (ta) => flow(ta, fai);
}
export function join<A>(ta: Sync<Sync<A>>): Sync<A> {
return () => ta()();
}
export function chain<A, I>(fati: (a: A) => Sync<I>): (ta: Sync<A>) => Sync<I> {
return (ta) => flow(ta, fati, (x) => x());
}
export function extend<A, I>(
ftai: (ta: Sync<A>) => I,
): (ta: Sync<A>) => Sync<I> {
return (ta) => () => ftai(ta);
}
export function reduce<A, O>(
foao: (o: O, a: A) => O,
o: O,
): (ta: Sync<A>) => O {
return (ta) => foao(o, ta());
}
export function traverse<V extends Kind>(
A: Applicative<V>,
): <A, I, J, K, L, M>(
faui: (a: A) => $<V, [I, J, K], [L], [M]>,
) => (ta: Sync<A>) => $<V, [Sync<I>, J, K], [L], [M]> {
return (faui) => (ta) => pipe(faui(ta()), A.map(of));
}
export const MonadSync: Monad<KindSync> = { of, ap, map, join, chain };
export const ExtendsSync: Extend<KindSync> = { map, extend };
export const TraversableSync: Traversable<KindSync> = { map, reduce, traverse };