a little pointless work
This commit is contained in:
parent
120aaee0e3
commit
e5d436e1cd
1 changed files with 8 additions and 3 deletions
|
@ -47,11 +47,16 @@ Each of these functors accepts an instance of a less general structure and uses
|
|||
|
||||
The more involved implementation in `ApplicativeOfMonad` is where we get some options in terms of implementation and also, not unrelatedly, where our problems arise. Because it turns out that there are multiple ways to implement the derivation functor--- also multiple ways to implement a particular monad or applicative--- it becomes hard to predict whether a derived implementation is the expected one without resorting to _ad hoc_ testing, testing that rather defeats the point of "gratis"[^low-effort]. The `apply` function, shown above, is derived from `bind` and `return` by threading `x` and `f` into the context through bind (as `y` and `g`, respectively), thus "stripping off" the context in the body of the lambda, then applying `g` to `y` to obtain a fresh `'b`, and finally passing that `'b` to `M.return`, thus producing a `'b M.t`, which of course is also an `'a t`, since `type 'a t = 'a M.t`[^with-type].
|
||||
|
||||
To explore concretely how deriving instances can go wrong, consider the following `BarMonad.
|
||||
To explore concretely how deriving instances can go wrong, consider the following `EitherMonad`.
|
||||
|
||||
```ocaml
|
||||
module BarMonad : Monad with type 'a t = 'a bar = struct
|
||||
...
|
||||
type ('a, 'b) either = A of 'a | B of 'b
|
||||
|
||||
module EitherMonad (T : sig type t end) : Monad with type 'a t = ('a, T.t) either = struct
|
||||
return x = [x]
|
||||
let rec bind (f : 'a -> 'b list) : 'a list -> 'b list = function
|
||||
| [] -> []
|
||||
| x :: xs -> f x @ bind f xs
|
||||
end
|
||||
```
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue