merge
This commit is contained in:
parent
02c92e795f
commit
a056164bd7
3 changed files with 9 additions and 8 deletions
|
@ -66,9 +66,8 @@ Here we see the completed implementation of the `list` monad in the module `List
|
||||||
|
|
||||||
[^capture-define]: TODO: be explicit about how monads exist independently and we are _capturing_ them in the particular language of ocaml. `list` forms a monad whether we actually implement that monad, or not
|
[^capture-define]: TODO: be explicit about how monads exist independently and we are _capturing_ them in the particular language of ocaml. `list` forms a monad whether we actually implement that monad, or not
|
||||||
|
|
||||||
A "functor" in OCaml parlance is distinct from anything called a "functor" elsewhere, being essentially a function from modules to modules. For practical reasons, modules and value-level programs are stratified from one another in OCaml, so a functor does not literally have a function type, but the mental model is still basically correct. We will encounter some functors of both sorts later on.
|
|
||||||
(aside: this stratification is not theoretically needed, re 1ml)
|
|
||||||
|
|
||||||
[^action-std]: This gives rise to a standard term. See [Monads as Computations](https://wiki.haskell.org/Monads_as_computation).
|
[^action-std]: This gives rise to a standard term. See [Monads as Computations](https://wiki.haskell.org/Monads_as_computation).
|
||||||
|
|
||||||
So the list monad allows us to write non-determinsitic code in much the same style as we would write fundamentally simpler determinstic code
|
So the list monad allows us to write non-determinsitic code in much the same style as we would write fundamentally simpler determinstic code
|
||||||
|
|
||||||
|
(aside: this stratification is not theoretically needed, re 1ml)
|
||||||
|
|
|
@ -39,10 +39,12 @@ module FunctorOfMonad (M : Monad) :
|
||||||
end
|
end
|
||||||
```
|
```
|
||||||
|
|
||||||
It turns out that there are multiple ways to implement the derivation functors--- also multiple ways to implement a particular monad ---and they don't all behave the same, which means it's hard to predict whether the more-general, derived implementations are the "natural" ones that you expected to get without _ad hoc_ testing, which obviously rather defeats the point of "free".
|
It turns out that there are multiple ways to implement the derivation functors--- also multiple ways to implement a particular monad ---and they don't all behave the same, which means it's hard to predict whether the more-general, derived implementations are the "natural" ones that you expected to get without _ad hoc_ testing, which obviously rather defeats the point of "free". On the other hand, the derivations here can be performed pretty mechanically, with little insight, by following the types in much the same way one might mechanically prove an easy proposition.
|
||||||
|
|
||||||
On the other hand, the derivations here can be performed pretty mechanically, with little insight, by following the types in much the same way one might mechanically prove a simple proposition. So it _is_ a relatively low-effort and low-investment activity.
|
***
|
||||||
|
|
||||||
TODO: explain functors and `with type`.
|
The modules above that seem to have parameters, do; these modules are called "functors". A functor in OCaml parlance is distinct from anything called a "functor" elsewhere, being essentially a function from modules to modules. For practical reasons, modules and value-level programs are stratified from one another in OCaml, so a functor does not literally have a function type, but the mental model is still basically correct.
|
||||||
|
|
||||||
|
A subtlety of the OCaml module system is that if a module is defined with a particular `module type` a.k.a. signature attached, e.g. `module M : S = struct...`, all the types that are abstract in the signature `S` will _also_ be abstract in the module itself. This means that the compiler can't see or be convinced that for some `F (M)` with `type t = M.t` in `F`, `M.t` and `(F (M)).t` are equal. This is because both types are abstract, meaning the underlying type is not available. To fix this, we can explicitly expose the equality by using the `with type` construct. In the above, `Functor with type 'a t = 'a M.t`--- for example ---exposes the equality of the two types, so that functions defined as expecting arguments of `'a t` can accepts `'a M.t`, and _vice versa_.
|
||||||
|
|
||||||
[^falsehood]: Unsurprisingly, that's a lie. You have to buy a `Monad` first.
|
[^falsehood]: Unsurprisingly, that's a lie. You have to buy a `Monad` first.
|
|
@ -2,5 +2,5 @@
|
||||||
max-width: 900px;
|
max-width: 900px;
|
||||||
margin-left: auto;
|
margin-left: auto;
|
||||||
margin-right: auto;
|
margin-right: auto;
|
||||||
overflow: visible;
|
overflow: auto;
|
||||||
}
|
}
|
Loading…
Add table
Add a link
Reference in a new issue