-So we've defined a Tree monad:
-
- type 'a tree = Leaf of 'a | Node of ('a tree) * ('a tree);;
- let tree_unit (a: 'a) : 'a tree = Leaf a;;
- let rec tree_bind (u : 'a tree) (f : 'a -> 'b tree) : 'b tree =
- match u with
- | Leaf a -> f a
- | Node (l, r) -> Node (tree_bind l f, tree_bind r f);;
-
-What's this have to do with the `tree_monadize` functions we defined earlier?
-
- let rec tree_monadize (t : 'a tree) (f : 'a -> 'b reader) : 'b tree reader =
- match t with
- | Leaf a -> reader_bind (f a) (fun b -> reader_unit (Leaf b))
- | Node (l, r) -> reader_bind (tree_monadize l f) (fun l' ->
- reader_bind (tree_monadize r f) (fun r' ->
- reader_unit (Node (l', r'))));;
-
-... and so on for different monads?
-
-Well, notice that `tree\_monadizer` takes arguments whose types
-resemble that of a monadic `bind` function. Here's a schematic bind
-function compared with `tree\_monadizer`:
-
- bind (u:'a Monad) (f: 'a -> 'b Monad): 'b Monad
- tree\_monadizer (u:'a Tree) (f: 'a -> 'b Monad): 'b Tree Monad
-
-Comparing these types makes it clear that `tree\_monadizer` provides a
-way to distribute an arbitrary monad M across the leaves of any tree to
-form a new tree inside an M box.