An Algebraic Effect System for Golang.
1package fx
2
3func ContraMap[V, S, R any](f func(R) S) func(Fx[S, V]) Fx[R, V] {
4 return func(e Fx[S, V]) Fx[R, V] {
5 if e.res != nil {
6 return Stop(func() Fx[R, V] { return ContraMap[V](f)(e.res()) })
7 }
8 if e.imm != nil {
9 return Const[R](e.imm())
10 }
11 return Pending(func(r R) Fx[R, V] {
12 return ContraMap[V](f)(e.sus(f(r)))
13 })
14 }
15}
16
17func MapM[S, U, V any](f func(U) Fx[S, V]) func(Fx[S, U]) Fx[S, V] {
18 return FlatCont(identity, identity, f)
19}
20
21func MapH[S, V, U any](f func(V) U) func(Fx[S, V]) Fx[S, U] {
22 return MapM(func(v V) Fx[S, U] { return Const[S](f(v)) })
23}
24
25func Map[S, V, U any](e Fx[S, V], f func(V) U) Fx[S, U] {
26 return MapH[S](f)(e)
27}
28
29func FlatMap[A, U, B, V any](e Fx[A, U], f func(U) Fx[B, V]) Fx[And[A, B], V] {
30 return FlatMapH[A](f)(e)
31}
32
33func FlatMapH[A, U, B, V any](f func(U) Fx[B, V]) func(Fx[A, U]) Fx[And[A, B], V] {
34 return FlatCont[And[A, B]](left, right, f)
35}
36
37func FlatCont[N, A, U, B, V any](amap func(N) A, bmap func(N) B, fmap func(U) Fx[B, V]) func(Fx[A, U]) Fx[N, V] {
38 return Then(amap, func(u U) Fx[N, V] { return Then(bmap, Const[N, V])(fmap(u)) })
39}