···11+package fx
22+33+func ProvideFirstLeft[A, B, C, V any](e Fx[And[And[A, C], B], V], a A) Fx[And[C, B], V] {
44+ return AndFlat(ProvideLeft(AndNest(e), a))
55+}
66+77+func ProvideFirstRight[A, B, D, V any](e Fx[And[A, And[B, D]], V], b B) Fx[And[A, D], V] {
88+ return AndSwap(ProvideFirstLeft(AndSwap(e), b))
99+}
1010+1111+func ProvideFirsts[A, B, C, D, V any](e Fx[And[And[A, C], And[B, D]], V], a A, b B) Fx[And[C, D], V] {
1212+ return ProvideFirstRight(ProvideFirstLeft(e, a), b)
1313+}
1414+1515+func Provide[S, V any](e Fx[S, V], s S) Fx[Nil, V] {
1616+ return ProvideLeft(AndNil(e), s)
1717+}
1818+1919+func ProvideBoth[A, B, V any](e Fx[And[A, B], V], a A, b B) Fx[Nil, V] {
2020+ return Provide(ProvideLeft(e, a), b)
2121+}
2222+2323+func ProvideRight[A, B, V any](e Fx[And[A, B], V], b B) Fx[A, V] {
2424+ return ProvideLeft(AndSwap(e), b)
2525+}
2626+2727+func ProvideLeft[A, B, V any](e Fx[And[A, B], V], a A) Fx[B, V] {
2828+ if e.res != nil {
2929+ return Stop(func() Fx[B, V] { return ProvideLeft(e.res(), a) })
3030+ }
3131+ if e.imm != nil {
3232+ return Const[B](e.imm())
3333+ }
3434+ return Pending(func(b B) Fx[B, V] {
3535+ var ab And[A, B] = func() (A, B) { return a, b }
3636+ var loop func(e Fx[And[A, B], V]) Fx[B, V]
3737+ loop = func(e Fx[And[A, B], V]) Fx[B, V] {
3838+ for {
3939+ e = e.sus(ab)
4040+ if e.res != nil {
4141+ return Stop(func() Fx[B, V] { return loop(e.res()) })
4242+ }
4343+ if e.imm != nil {
4444+ return Const[B](e.imm())
4545+ }
4646+ }
4747+ }
4848+ return loop(e)
4949+ })
5050+}
+46
fx/stop.go
···11+package fx
22+33+// Creates an stopped effect from a resume function
44+func Stop[S, V any](e func() Fx[S, V]) Fx[S, V] {
55+ return Fx[S, V]{res: e}
66+}
77+88+// Resume an effect if it was previously stopped.
99+func Resume[S, V any](e Fx[S, V]) Fx[S, V] {
1010+ if e.res != nil {
1111+ return e.res()
1212+ }
1313+ if e.imm != nil {
1414+ return Const[S](e.imm())
1515+ }
1616+ return Pending(func(s S) Fx[S, V] { return Resume(e.sus(s)) })
1717+}
1818+1919+// Replace with y if x is already Halted. Otherwise x continues.
2020+func Replace[S, V any](y func() Fx[S, V]) func(Fx[S, V]) Fx[S, V] {
2121+ return func(x Fx[S, V]) Fx[S, V] {
2222+ if x.res != nil {
2323+ return y()
2424+ }
2525+ if x.imm != nil {
2626+ return Const[S](x.imm())
2727+ }
2828+ return Pending(func(s S) Fx[S, V] { return Replace(y)(x.sus(s)) })
2929+ }
3030+}
3131+3232+// An stopped effect that panics if resumed.
3333+// Only useful with Replace.
3434+//
3535+// For example, an Abort effect halts since it has no possible value for V
3636+// but then its Handler can Replace the halted effect with an Error value.
3737+// See: abort/result.go
3838+func Halt[S, V any]() Fx[S, V] {
3939+ return Stop(func() Fx[S, V] {
4040+ return Fx[S, V]{
4141+ imm: func() V {
4242+ panic("tried to Resume a halted effect. try using Replace instead")
4343+ },
4444+ }
4545+ })
4646+}