-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathbitraversable.ts
More file actions
65 lines (57 loc) · 2.41 KB
/
bitraversable.ts
File metadata and controls
65 lines (57 loc) · 2.41 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
61
62
63
64
65
import { Box2, Kind, Constraint, MinBox1 } from 'data/kind'
import { Bifunctor } from 'data/bifunctor'
import { BiFoldable } from 'data/bifoldable'
import { Applicative } from 'ghc/base/applicative'
import { Monad } from 'ghc/base/monad/monad'
import { id } from 'ghc/base/functions'
export type BiTraversableBase = Bifunctor &
BiFoldable & {
bitraverse<A, B, C, D>(
app: Applicative,
f: (a: A) => MinBox1<C>,
g: (b: B) => MinBox1<D>,
fab: Box2<A, B>,
): MinBox1<Box2<C, D>>
bisequenceA<A, B>(app: Applicative, tfab: Box2<MinBox1<A>, MinBox1<B>>): MinBox1<Box2<A, B>>
}
export type BiTraversable = BiTraversableBase & {
bimapM<A, B, C, D>(m: Monad, f: (a: A) => MinBox1<C>, g: (b: B) => MinBox1<D>, fab: Box2<A, B>): MinBox1<Box2<C, D>>
bisequence<A, B>(m: Monad, tfab: Box2<MinBox1<A>, MinBox1<B>>): MinBox1<Box2<A, B>>
kind: (_: (_: '*') => (_: '*') => '*') => Constraint
}
export type BaseImplementation = Partial<Pick<BiTraversableBase, 'bitraverse' | 'bisequenceA'>> &
(Pick<BiTraversableBase, 'bitraverse'> | Pick<BiTraversableBase, 'bisequenceA'>)
export const kindOf =
(_: BiTraversable): Kind =>
(_: (_: '*') => (_: '*') => '*') =>
'Constraint' as Constraint
export const bitraversable = (
base: BaseImplementation,
bifunctor: Bifunctor,
bifoldable: BiFoldable,
): BiTraversable => {
const result: BiTraversableBase = {
...bifunctor,
...bifoldable,
bitraverse: base.bitraverse as BiTraversableBase['bitraverse'],
bisequenceA: base.bisequenceA as BiTraversableBase['bisequenceA'],
}
if (!base.bitraverse && base.bisequenceA) {
result.bitraverse = <A, B, C, D>(
app: Applicative,
f: (a: A) => MinBox1<C>,
g: (b: B) => MinBox1<D>,
fab: Box2<A, B>,
): MinBox1<Box2<C, D>> => result.bisequenceA(app, result.bimap(f, g, fab))
}
if (!base.bisequenceA && base.bitraverse) {
result.bisequenceA = <A, B>(app: Applicative, tfab: Box2<MinBox1<A>, MinBox1<B>>): MinBox1<Box2<A, B>> =>
result.bitraverse(app, id, id, tfab)
}
return {
...result,
bimapM: (m, f, g, fab) => result.bitraverse(m, f, g, fab),
bisequence: (m, tfab) => result.bisequenceA(m, tfab),
kind: kindOf(null as unknown as BiTraversable) as (_: (_: '*') => (_: '*') => '*') => 'Constraint',
}
}