48 lines
No EOL
1.8 KiB
Text
48 lines
No EOL
1.8 KiB
Text
# Functors and Applicatives for Free[^falsehood]
|
|
|
|
It's usually possible to derive implementations of general structures from those of more specific ones, e.g. `Applicative` from `Monad` and `Functor` from `Applicative`. Here's how to do it and and why it's probably best avoided.
|
|
|
|
```ocaml
|
|
module type Functor = sig
|
|
type 'a t
|
|
val map : ('a -> 'b) -> 'a t -> 'b t
|
|
end
|
|
|
|
module type Applicative = sig
|
|
type 'a t
|
|
val pure : 'a -> 'a t
|
|
val apply : ('a -> 'b) t -> 'a t -> 'b t
|
|
end
|
|
|
|
module type Monad = sig
|
|
type 'a t
|
|
val return : 'a -> 'a t
|
|
val bind : ('a -> 'b t) -> 'a t -> 'b t
|
|
end
|
|
|
|
module ApplicativeOfMonad (M : Monad) :
|
|
Applicative with type 'a t = 'a M.t = struct
|
|
type 'a t = 'a M.t
|
|
let pure = M.return
|
|
let apply f x = M.(bind (fun y -> bind (fun g -> return (g y)) f) x)
|
|
end
|
|
|
|
module FunctorOfApplicative (A : Applicative) :
|
|
Functor with type 'a t = 'a A.t = struct
|
|
type 'a t = 'a A.t
|
|
let map f x = A.(apply (pure f) x)
|
|
end
|
|
|
|
module FunctorOfMonad (M : Monad) :
|
|
Functor with type 'a t = 'a M.t = struct
|
|
include FunctorOfApplicative(ApplicativeOfMonad(M))
|
|
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".
|
|
|
|
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`.
|
|
|
|
[^falsehood]: Unsurprisingly, that's a lie. You have to buy a `Monad` first. |