···77type AbortFx[E, V any] = fx.Fx[AbortAb[E], V]
8899func Abort[V, E any](e E) AbortFx[E, V] {
1010- return fx.Map(fx.Handle[AbortFn[E]](e), func(_ fx.Nil) V {
1010+ return fx.Map(fx.Suspend[AbortFn[E]](e), func(_ fx.Nil) V {
1111 panic("unhandled abort effect")
1212 })
1313}
+1-1
abort/abort_test.go
···3030 panic("BUG: mapping on aborted eff should be unreachable")
3131 })
3232 // Another way of applying the abort handler.
3333- x := fx.ProvideLeft(fx.Handle[ResultHn[Ok, Err]](e), AbortHandler[Ok, Err])
3333+ x := fx.ProvideLeft(fx.Suspend[ResultHn[Ok, Err]](e), AbortHandler[Ok, Err])
3434 var r Result[Ok, Err] = fx.Eval(x)
3535 val, err := r()
3636 if *err != "ahhhh" {
···11# Abort
2233`Abort[V, E](E)` aborts a computation of `V` with `E`.
44-The abort Handler transforms these effects into `Result[V, E]`.
44+55+When aborted, a computation is *halted*, meaning that any `Map` or `FlatMap` operation over it will not be executed.
5666-- Implementation [abort.go](https://github.com/vic/fx.go/blob/main/abort/abort.go)
77+The `AbortHandler` replaces aborted effects (those computations where Abort was called) with a `Result` with `E`. Otherwise if the effect was never aborted, a `Result` with `V` is returned.
88+99+1010+- Implementation
1111+ - [abort.go](https://github.com/vic/fx.go/blob/main/abort/abort.go)
1212+ - [result.go](https://github.com/vic/fx.go/blob/main/abort/result.go)
713- Tests [abort_test.go](https://github.com/vic/fx.go/blob/main/abort/abort_test.go)
+12-14
book/src/basics.md
···6677The most basic of all possible effects are *Immediate* effects. These are effects of type `Fx[Nil, V]`, meaning that they have no ability requirements (`Nil`) and evaluate to a value (`V`).
8899-Immediate effects are created using the `Pure(*V) Fx[Nil, V]` function. The name `Pure` relates to the convential naming on effect systems for moving (lifting) a value `V` into the domain of `Fx`.
99+Immediate effects are created using the `Pure(V) Fx[Nil, V]` function.
10101111-As you can see, `Pure(*V)` takes a pointer to an *existing* value `V`, that means that a pure effect just holds a pointer to an already known value instead of trying to compute it.
1111+As you can see, `Pure(V)` takes an *existing* value `V`, that means that a pure effect just holds an already known value instead of trying to compute it.
12121313-The pointer given to `Pure` can be retrieved by using `Eval(Fx[Nil, V]) *V`. Only effects that have no requirements (`Nil`) can be evaluated.
1313+The value given to `Pure` can be retrieved by using `Eval(Fx[Nil, V]) V`. Only effects that have no requirements (`Nil`) can be evaluated.
14141515```go
1616import ( fx "github.com/vic/fx.go" )
···1818func PureExample() {
1919 v := "Hello World"
2020 // Code annotated with types for clarity
2121- var effect fx.Fx[fx.Nil, string] = fx.Pure(&v)
2222- var result *string = fx.Eval(effect)
2323- assert(*result == v)
2121+ var effect fx.Fx[fx.Nil, string] = fx.Pure(v)
2222+ var result string = fx.Eval(effect)
2323+ assert(result == v)
2424}
2525```
2626···4141 // Code annotated with types for clarity
4242 var effect fx.Fx[string, int] = fx.Func(LengthOfString)
4343 var requirement string = "Hello World"
4444- var provided fx.Fx[fx.Nil, int] = fx.Provide(effect, &requirement)
4545- var result *int = fx.Eval(provided)
4646- assert(*result == len(requirement))
4444+ var provided fx.Fx[fx.Nil, int] = fx.Provide(effect, requirement)
4545+ var result int = fx.Eval(provided)
4646+ assert(result == len(requirement))
4747}
4848```
49495050From the code above:
51515252- `Func(func (S) V)` produces a _pending_ effect of type `Fx[S, V]`.
5353-- `Provide(Fx[S, V], *S)` discharges the `S` requirement and returns `Fx[Nil, V]`.
5353+- `Provide(Fx[S, V], S)` discharges the `S` requirement and returns `Fx[Nil, V]`.
5454 Note that *no computation* is performed in this step. `Fx[Nil, V]` is still a description of a program, and `V` has not been computed yet, nor any side-effect has been performed.
5555-- `Eval(Fx[Nil, V])` will actually perform the computation of `V`, since all `non-Nil` requirements have already , the computation can be performed.been provided.
5555+- `Eval(Fx[Nil, V])` will actually perform the computation of `V`. Since all `non-Nil` requirements have already been provided, the computation can be run.
565657575858-These two are the most basic effects in `Fx.go`, and using them we have shown the essential `fx.Provide` and `fx.Eval` APIs.
5959-6060-More interesting effects will be presented as we explore the topics of Handlers and combinators.5858+These two are the most basic effects in `Fx.go`. More interesting effects will be presented as we explore the topics of effect Rquests and Handlers.
···17171818## Abilities
19192020-In `Fx[S, V]`, `S` is said to be the *Ability* (sometimes also referred as the _set_ of *Abilities*, *Capabilities* or *Requirements*) that are needed for computing `V`.
2020+In `Fx[S, V]`, `S` is said to be the *Ability* (sometimes also referred as the _set_ of *Abilities*, *Capabilities*, *Effect Environment* or *Effect Requirements*) that are needed for computing `V`.
21212222Abilities describe the external resources that would be needed, as well as the _side-effects_ that are possible while computing `V`.
2323···35353636A *Handler* for the `S` ability is a particular _interpretation_ of what `S` means.
37373838-It is the Handler of `S` the only _side-effectful_ portion of your programs. It is possible and quite common to have different handlers (interpretations) for the same Ability, and each Handler decides _how/when_ to perform world-modifying _side-effects_.
3838+Handlers are the only _side-effectful_ portion of your programs. It is possible, and quite common, to have different handlers (interpretations) for the same Ability, and each Handler decides _how/when_ to perform world-modifying _side-effects_.
39394040For example, for an _http-request_ ability you can have a *test-handler* that just mock responses to fixed values so that you can easily assert on known values on your tests. You could also have a *live-handler* that actually performs requests via the network for production runs.
+1
book/src/contributing.md
···11# Contributing
2233+Yes, please. All PRs are welcome, documentation, code improvements, ideas or suggestions, ways to improve this book prose, etc.
+28-24
book/src/handlers.md
···11# Handlers
2233-A _Handler_ is an effect transformer function of type `func(Fx[R, U]) Fx[S, V]`. Handlers are free to change the effect requirements, they tipically reduce the requirement set, but they could also introduce new requirements. Also the result value can be changed or be the same.
33+A _Handler_ is an effect transformation function of type `func(Fx[R, U]) Fx[S, V]`.
44+55+Handlers are free to change the effect requirements, they tipically reduce the requirement set, but they could also introduce new requirements. They can also change or keep the result type.
4657## Handling an effect
6879Lets re-write our previous "length of string" function as a Handler.
810911```go
1010-type LenFn = func(string) fx.Fx[fx.Nil, int]
1212+type LenFn func(string) Fx[Nil, int]
11131214// Code is type annotated for clarity
1313-var lenFx fx.Fx[fx.And[LenFn, fx.Nil], int] = fx.Suspend[LenFn]("hello")
1515+var lenFx Fx[And[LenFn, Nil], int] = fx.Suspend[LenFn]("hello")
14161515-// type is not needed but just added for clarity.
1616-type LenHn = func(fx.Fx[fx.And[LenFn, fx.Nil], int]) fx.Fx[fx.Nil, int]
1717+// type of a handler. not needed but added for clarity.
1818+type LenHn func(Fx[And[LenFn, Nil], int]) Fx[Nil, int]
17191820var handler LenHn = fx.Handler(func(s string) fx.Fx[fx.Nil, int] {
1919- truth := len(s)
2020- return fx.Pure(&truth)
2121+ return fx.Pure(len(s))
2122})
22232323-// apply the handler to lenFx
2424+// apply the handler directly to lenFx
2425var x *int = fx.Eval(handler(lenFx))
2526assert(*x == 5)
2627```
27282828-As you might guess, `fx.Handler` is just a wrapper for `ProvideLeft(Fx[And[Fn, S], O], *Fn) Fx[S, O]` where `Fn = func(I) Fx[S, O]`, an request-effect function.
2929+As you might guess, `fx.Handler` is just a wrapper for `ProvideLeft(Fx[And[Fn, S], O], Fn) Fx[S, O]` where `Fn = func(I) Fx[S, O]`, an request-effect function.
293030313132## Requesting Handlers (effect-transformers) from the environment.
32333333-Of course, you can also request that a particular effect transformer (Handler) be present as a requirement of some computation. In this way the handler is provided only once but can be applied anywhere it is needed inside the program.
3434+Of course, you can also request that a particular effect transformer (Handler) be present as a requirement of some computation. This way the handler is provided only once but can be applied anywhere it is needed inside the program.
34353536```go
3637// Same examples as above with some more types for clarity
3737-type LenFn = func(string) fx.Fx[fx.Nil, int]
3838-type LenFx = fx.Fx[fx.And[LenFn, fx.Nil], int]
3939-type LenHn = func(LenFx) fx.Fx[fx.Nil, int]
40384141-var lenFx LenFx = fx.Suspend[LenFn]("hello")
3939+// effect-request function type.
4040+type LenFn func(string) Fx[Nil, int]
4141+// effect handler type
4242+type LenHn = func(Fx[And[LenFn, Nil], int]) Fx[Nil, int]
42434343-// Request that an implementation of LenHn transformer
4444-// is available in the environment and it be applied to lenFx.
4545-var lenAp Fx[And[LenHn, Nil], int] = fx.Apply[LenHn](lenFx)
4444+// effect ability
4545+type LenAb = And[LenHn, Nil]
4646+// effect type producing V
4747+type LenFx[V any] = fx.Fx[LenAb, V]
4848+4949+// Same as: Suspend[LenHn](Suspend[LenFn](input))
5050+var lenFx LenFx = fx.Handle[LenHn]("hello")
46514752var handler LenHn = fx.Handler(func(s string) fx.Fx[fx.Nil, int] {
4848- truth := len(s)
4949- return fx.Pure(&truth)
5353+ return fx.Pure(len(s))
5054})
51555252-// Now instead of applying the handler directly to each effect it
5353-// must handle, we provide it into the environment.
5454-var provided Fx[Nil, int] = fx.ProvideLeft(lenAp, &handler)
5555-val x *int = fx.Eval(provided)
5656-assert(*x == 5)
5656+// Now instead of applying the handler directly to each effect
5757+// we provide it into the environment.
5858+var provided Fx[Nil, int] = fx.ProvideLeft(lenFx, handler)
5959+val x int = fx.Eval(provided)
6060+assert(x == 5)
5761```
+11-12
book/src/http.md
···2020// For simplicity out response is just an string: The response body.
2121type HttpRs string
22222323-// Type of the request-effect function. This will be implemented
2424-// by some handler to provide actual responses.
2323+// Type of the effect-request function.
2424+// This will be implemented by some handler to provide actual responses.
2525//
2626// fx.Nil in the result type indicates that our Http ability does
2727// not requires any other ability.
2828-type HttpFn = func(HttpRq) fx.Fx[fx.Nil, HttpRs]
2828+type HttpFn func(HttpRq) fx.Fx[fx.Nil, HttpRs]
29293030-// Type of the Handler (effect transformer) that handles requests.
3030+// Type of the Http Handler that discharges effect requirements
3131type HttpHn = func(fx.Fx[fx.And[HttpFn, fx.Nil], HttpRs]) fx.Fx[fx.Nil, HttpRs]
32323333-// Type of an effect ability (requires the handler) and additional abilities.
3333+// Type of the Http Ability: the handler and aditional abilities.
3434type HttpAb = fx.And[HttpHn, fx.Nil]
35353636// An http effect that produces V
···38383939// An effect of HTTP GET requests.
4040func Get(url HttpRq) HttpFx[HttpRs] {
4141- // Request[HttpHn](input) is the same as Apply[HttpHn](Suspend[HttpFn](input))
4242- return fx.Request[HttpHn](url)
4141+ return fx.Handle[HttpHn](url)
4342}
44434544// A program that computes the respose length of https://example.org
···5049}
51505251func TestProgram(t *testing.T) {
5353- httpHandler := fx.Handler(func(r HttpRq) fx.Fx[fx.Nil, HttpRs] {
5252+ var httpHandler HttpHn = fx.Handler(func(r HttpRq) fx.Fx[fx.Nil, HttpRs] {
5453 mock := HttpRs("example")
5554 return fx.Pure(&mock)
5655 })
5757- var provided fx.Fx[fx.Nil, int] = fx.ProvideLeft(Program(), &httpHandler)
5858- var result *int = fx.Eval(provided)
5959- if *result != len("example") {
6060- t.Errorf("Unexpected result %v", *result)
5656+ var provided fx.Fx[fx.Nil, int] = fx.ProvideLeft(Program(), httpHandler)
5757+ var result int = fx.Eval(provided)
5858+ if result != len("example") {
5959+ t.Errorf("Unexpected result %v", result)
6160 }
6261}
6362
+10-12
book/src/requests.md
···4455A function of type `func(I) Fx[S, O]` is said to take an _effect-request_ `I` and produce an *suspended* effect `Fx[S, O]`.
6677-For example, the function `func(HttpReq) Fx[HttpService, HttpRes]` states that given an `HttpReq` request you can obtain an `HttpRes` response, *provided* that an `HttpService` is available.
77+An example, is the function `func(HttpReq) Fx[HttpService, HttpRes]` we saw in the [previous](./requirements/apply.html) chapter.
8899Using the "length of string" example of the previous chapters, we can use it to model an effect request:
1010···2020Different implementations of `LenFn` can be provided to the `lenFx` effect.
21212222```go
2323-var bad LenFn = func(_ string) fx.Fx[fx.Nil, int] {
2424- lies := 42
2525- return fx.Pure(&lies)
2323+var lies LenFn = func(_ string) fx.Fx[fx.Nil, int] {
2424+ return fx.Pure(42)
2625}
2727-var good LenFn = func(s string) fx.Fx[fx.Nil, int] {
2828- truth := len(s)
2929- return fx.Pure(&truth)
2626+var truth LenFn = func(s string) fx.Fx[fx.Nil, int] {
2727+ return fx.Pure(len(s))
3028}
31293232-var x *int = fx.Eval(fx.ProvideLeft(lenFx, &bad))
3333-assert(*x == 42)
3030+var x int = fx.Eval(fx.ProvideLeft(lenFx, lies))
3131+assert(x == 42)
34323535-var y *int = fx.Eval(fx.ProvideLeft(lenFx, &good))
3636-assert(*y == 5)
3333+var y int = fx.Eval(fx.ProvideLeft(lenFx, truth))
3434+assert(y == 5)
3735```
38363939-Notice that by delaying which implementation of `LenFn` is used, the `lenFx` program description includes the effect-request `"hello"` and knows the general form of its response `Fx[Nil, int]`, but knows nothing about which particular interpretation of `LenFn` will be used.3737+Notice that by delaying which implementation of `LenFn` is used, the `lenFx` program description includes the effect request `"hello"` and knows the general form of its response `Fx[Nil, int]`, but knows nothing about which particular interpretation of `LenFn` will be used.
+9-64
book/src/requirements.md
···2233So far, we have seen that an effect `Fx[S, V]` can have `S` be `Nil` for effects that can be evaluated right away and non-`Nil` for those pending effects that still need to be provided some value.
4455-In this chapter we will talk about Composite requirement types using the `And` type. And how different types of functions/effects can represent the very same computation. We also look at similarities with higher-order functions in functional-programming and how rotating or re-arranging effect requirements is indifferent in `Fx.go`. Finally, we show some the`And*` and `Provide*` combinators that can help you reshape your effect requirements.
55+In this chapter we will talk about aggregating requirements using the `And` type. And how different types of functions/effects can represent the very same computation. We also look at similarities with higher-order functions in functional-programming and how rotating or re-arranging effect requirements is indifferent in `Fx.go`. Finally, we show some the`And*` and `Provide*` combinators that can help you reshape your effect requirements.
6677-## `And[A, B]` composed Requirement Types
77+## Composite requirements
8899Using the same "length of string" function from the previous chapters, we can describe it in different ways.
10101111```go
1212// This is an strange way of writing `func(string) int`.
1313-// But this shape is used to understand the types bellow.
1313+// But this shape can help to understand the types bellow.
1414//
1515-// Focus on what are the requirements needed to perform
1616-// a computation, more than the shape of the type.
1515+// Focus your attention on the requirements that are
1616+// needed for a computing a value.
1717//
1818// In particular, note that `Fx[Nil, V]` is like a `func() V`
1919-func LenghtOfString(s string) func() int {
1919+func LengthOfString(s string) func() int {
2020 return func() int { return len(s) }
2121}
22222323+// The type of LengthOfString expressed as an effect request.
2324type LenFn = func(string) Fx[Nil, int]
2425```
2526···34353536The last three examples represent nested effects and are equivalent to functions of arity > 1 or functions that return functions.
36373737-`And[A, B]` is the requirement for both `A` and `B` abilities. Notice on the last two examples, that they have their components swapped, however, its important to note that in `Fx.go`, _the *order* of the abilities on the requirement does not matter_ and can be freely swapped/joined/unjoined. More on this when we talk about `And*` combinators.
3838+`And[A, B]` is the requirement for both `A` and `B` abilities. Notice in the last two examples, that their components are swapped. It is important to note that in `Fx.go`, _the *order* of the abilities on And requirements does not matter_ and they can be freely swapped/joined/unjoined. More on this when we talk about `And*` combinators.
38393940Also, note that `And[A, Nil]` is equivalent to just `A`. All of these types represent the same type of computation and an effect can be transformed to any of those types freely.
4041···5960- `Fx[int, Fx[string, int]]`
6061- `Fx[And[int, string], int]`
61626262-An important thing to note is that in `Fx`, the *requirements are identified by their type* and not by their name, so they can be freely re-arranged or provided in any order. Note that `And[X, X]` is equivalent to just a single `X` requirement, and that `And[And[X, Y], And[Y, X]]` is also equivalent to `And[X, Y]`.
6363-6363+Note that `And[X, X]` is equivalent to just a single `X` requirement, and that `And[And[X, Y], And[Y, X]]` is also equivalent to `And[X, Y]`.
64646565-## `And*` Combinators.
6666-6767-There are some functions (more will be added as they are found useful) that help you re-arrange `And`ed effect requirements:
6868-6969-```go
7070-// Since `And[A, A]` is equivalent to just `A`.
7171-// Used to collapse Nil requirements just before evaluation.
7272-func AndCollapse(Fx[And[A, A], V]) Fx[A, V]
7373-7474-// Ands S with Nil in the effect requirements
7575-func AndNil(Fx[S, V]) Fx[And[S, Nil], V]
7676-7777-// Swaps A and B. Note: this has no impact on how computation is
7878-// performed, since requirements can be freely re-arranged.
7979-func AndSwap(Fx[And[A, B], V]) Fx[And[B, A], V]
8080-8181-8282-// FlatMaps the inner effect into the outer by
8383-// Anding their requirements.
8484-func AndJoin(Fx[A, Fx[B, V]]) Fx[And[A, B], V]
8585-8686-// Reverse of Join
8787-func AndDisjoin(Fx[And[A, B], V]) Fx[A, Fx[B, V]]
8888-8989-```
9090-9191-## `Provide*` Combinators.
9292-9393-These functions are used to provide requirements into effects. The result is another effect (no computation has been performed yet) but with less requirements.
9494-9595-```go
9696-// Discharges the single S requirement.
9797-func Provide(Fx[S, V], *S) Fx[Nil, V]
9898-9999-100100-// Discharges the requirement of A by providing it.
101101-func ProvideLeft(Fx[And[A, B], V], *A) Fx[B, V]
102102-103103-// Discharges the requirement of B by providing it.
104104-func ProvideRight(Fx[And[A, B], V], *B) Fx[A, V]
105105-106106-// Discharges both A and B
107107-func ProvideBoth(Fx[And[A, B], V], *A, *B) Fx[Nil, V]
108108-109109-110110-111111-// Provides A, the `CAAR` of the requirements list.
112112-func ProvideA(Fx[And[And[A, C], And[B, D]], V], *A) Fx[And[C, And[B, D]], V]
113113-114114-// Provides B, the `CADR` of the requirements list.
115115-func ProvideB(Fx[And[And[A, C], And[B, D]], V], *B) Fx[And[And[A, C], D], V]
116116-117117-// Provides A and B, the `CAAR` and `CADR` of the requirements list.
118118-func ProvideAB(Fx[And[And[A, C], And[B, D]], V], *A, *B) Fx[And[C, D], V]
119119-```
12065
+51
book/src/requirements/apply.md
···11+# Functional Requirements
22+33+As we have seen in the previous [Context](context.html) chapter, you can ask for any type to be part of an effect's environment.
44+55+You can also ask for functions of some type to be present and use them in your program descriptions without knowing their exact implementation.
66+77+For example, suppose we ask for a function that takes an integer. And then apply it to a value.
88+99+```go
1010+// The type of the function from int to int
1111+type OnInt func(int) nit
1212+1313+// Apply OnInt(12)
1414+var a Fx[OnInt, int] = Map(Ctx[OnInt](), func(f OnInt) int {
1515+ return f(12)
1616+})
1717+1818+// fx.Apply is just an abbreviation of the previous code:
1919+// It takes the type of a unary function and the value to apply.
2020+var b Fx[OnInt, int] = Apply[OnInt](12)
2121+```
2222+2323+Because `OnInt` is part of the environment, we only know its signature (its request and response type), but not the actual implementation of it. This way, different implementations of `OnInt` can be provided later.
2424+2525+2626+Now, suppose you have the following code:
2727+2828+```go
2929+type HttpRq string
3030+var url = HttpRq("https://example.org")
3131+3232+// `Http` is the type of an *effect request* function.
3333+// it takes a plain value and creates an effect.
3434+type Http func(HttpRq) Fx[HttpService, HttpRs]
3535+3636+// NOTE: applying to Http, creates a nested effect
3737+var a Fx[Http, Fx[HttpService, HttpRs]] = Apply[Http](url)
3838+3939+// Flatenning creates an Anded environment.
4040+var b Fx[And[Http, HttpService], HttpRs] = AndJoin(a)
4141+4242+4343+// Same as previous two lines:
4444+var x Fx[And[Http, HttpService], HttpRs] = Suspend[Http](url)
4545+```
4646+4747+`fx.Suspend` is an abbreviation of `AndJoin(Apply[Http](url))` for *effect requests* (functions returning an effect)
4848+4949+5050+This is the principle behind *suspended effect application* in `Fx.go` and is a fundamental part when we talk about effect [Requests](../requests.html) and [Handlers](../handlers.html).
5151+
+24
book/src/requirements/context.md
···11+# Context Requirements
22+33+The `Ctx[V]() Fx[V, V]` function creates an effect that requires some value `V` as part of the environment and evaluates to `V`.
44+55+It can be used to request the presence of some services (interfaces or collections of methods that produce related effects) or more generally, an evidence that a value `V` is part of the environment.
66+77+In the following example we simply map over an string to compute its length.
88+99+```go
1010+var eff Fx[string, int] = Map(Ctx[string](), LengthOfString)
1111+var result int = Eval(Provide(eff, "hello"))
1212+assert(result == len("hello"))
1313+```
1414+1515+Calling the `Const[S](V) Fx[S, V]` is like maping a context over a constant function.
1616+As you might have guessed, `Pure` is defined in terms of `Const`.
1717+1818+```go
1919+var a Fx[string, int] = Map(Ctx[string](), func(_ string) int { return 42 })
2020+var b Fx[string, int] = Const[string](42)
2121+2222+var c Fx[Nil, int] = Pure(22)
2323+var d Fx[Nil, int] = Const[Nil](22)
2424+```
+36
book/src/requirements/providers.md
···11+# Providing Requirements
22+33+*Effect requirements can be provided in any order* with no impact in the evaluation of the program.
44+55+66+## `Provide*` Combinators.
77+88+These functions are used to eliminate requirements from effects. Only when `Nil` is the only remaining requirement, the effect can be evaluated.
99+1010+The result of provide functions will always be another effect, meaning that no computation has been performed yet, nor any side-effect produced. The result is just another effect but with less requirements.
1111+1212+```go
1313+// Discharges the single S requirement.
1414+func Provide(Fx[S, V], S) Fx[Nil, V]
1515+1616+1717+// Discharges the requirement of A by providing it.
1818+func ProvideLeft(Fx[And[A, B], V], A) Fx[B, V]
1919+2020+// Discharges the requirement of B by providing it.
2121+func ProvideRight(Fx[And[A, B], V], B) Fx[A, V]
2222+2323+// Discharges both A and B
2424+func ProvideBoth(Fx[And[A, B], V], A, B) Fx[Nil, V]
2525+2626+2727+2828+// Provides A, the first part of the left And.
2929+func ProvideFirstLeft(Fx[And[And[A, C], And[B, D]], V], A) Fx[And[C, And[B, D]], V]
3030+3131+// Provides B, the first part of the right And.
3232+func ProvideFirstRight(Fx[And[And[A, C], And[B, D]], V], B) Fx[And[And[A, C], D], V]
3333+3434+// Provides A and B, the first part of both Ands.
3535+func ProvideFirsts(Fx[And[And[A, C], And[B, D]], V], A, B) Fx[And[C, D], V]
3636+```
+34
book/src/requirements/shuffling.md
···11+# Shuffling `And`ed requirements.
22+33+An important thing to note is that in `Fx.go`, *requirements are identified by their type* and not by name or position as in regular functions.
44+55+*Effect requirements can be freely re-arranged* with no impact in the meaning of the program.
66+77+88+## `And*` combinators.
99+1010+There are some functions (more will be added as they are found useful) that help you re-arrange `And`ed effect requirements.
1111+1212+Shuffling And requirements is useful because you might want to provide some requirements first than others even if they are not in the head position of the requirement list.
1313+1414+```go
1515+// Since `And[A, A]` is equivalent to just `A`.
1616+// Used to collapse Nil requirements just before evaluation.
1717+func AndCollapse(Fx[And[A, A], V]) Fx[A, V]
1818+1919+// Ands S with Nil in the effect requirements
2020+func AndNil(Fx[S, V]) Fx[And[S, Nil], V]
2121+2222+// Swaps A and B. Note: this has no impact on how computation is
2323+// performed, since requirements can be freely re-arranged.
2424+func AndSwap(Fx[And[A, B], V]) Fx[And[B, A], V]
2525+2626+2727+// FlatMaps the inner effect into the outer by
2828+// Anding their requirements.
2929+func AndJoin(Fx[A, Fx[B, V]]) Fx[And[A, B], V]
3030+3131+// Reverse of Join
3232+func AndDisjoin(Fx[And[A, B], V]) Fx[A, Fx[B, V]]
3333+3434+```
+5-2
book/src/rw.md
···2233A `Reader[T]` allows to read values of type `T` from the environment while `Writer[T]` allows to set them.
4455-- Implementation [rw.go](https://github.com/vic/fx.go/blob/main/rw/rw_test.go)
55+- Implementation
66+ - [read.go](https://github.com/vic/fx.go/blob/main/rw/read.go)
77+ - [write.go](https://github.com/vic/fx.go/blob/main/rw/write.go)
88+69- Tests [rw_test.go](https://github.com/vic/fx.go/blob/main/rw/rw_test.go)
71088-Read and Write Handlers take an effectful operation that can modify the external world. See `rh` and `wh` in `TestReadWrite`.1111+Read and Write Handlers take an effectful operation that can modify the external world. See `TestReadWrite`.