reader_unit (Node(ls, rs))))
in loop us);;
- let tree_reader_elevate (w : 'a reader) : 'a tree_reader =
- reader_bind w (fun a -> reader_unit (Leaf a))
+ let tree_reader_elevate (inner : 'a reader) : 'a tree_reader =
+ reader_bind inner (fun a -> reader_unit (Leaf a))
Recall our earlier definition of `tree_monadize`, specialized for the Reader monad:
(* the next line is equivalent to: tree_reader_elevate (f a) *)
reader_bind (f a) (fun b -> reader_unit (Leaf b))
| Node (l, r) ->
- reader_bind (tree_monadize f l) (fun l' ->
- reader_bind (tree_monadize f r) (fun r' ->
- reader_unit (Node (l', r'))));;
+ reader_bind (tree_monadize f l) (fun ls ->
+ reader_bind (tree_monadize f r) (fun rs ->
+ reader_unit (Node (ls, rs))));;
We rendered the result type here as `'b tree reader`, as we did in our earlier discussion, but as we can see from the above implementation of TreeT(Reader), that's the type of an `'b tree_reader`, that is, of a layered box consisting of TreeT packaging wrapped around an inner Reader box.
# let tree_reader = TR.distribute (fun i -> R.asks (fun e -> e i)) t1;;
# TR.run tree_reader (fun i -> i+i);;
- (*
- : int T.tree option =
Some
(T.Node
(T.Node (T.Leaf 4, T.Leaf 6),
T.Node (T.Leaf 10, T.Node (T.Leaf 14, T.Leaf 22))))
- *)
Here's a comparison of how distribute works for trees and how it works for lists:
# let tree_counter = TS.distribute (fun i -> S.(puts succ >> unit i)) t1 in
TS.run tree_counter 0;;
- (*
- : int T.tree option * S.store =
(Some
(T.Node
(T.Node (T.Leaf 2, T.Leaf 3),
T.Node (T.Leaf 5, T.Node (T.Leaf 7, T.Leaf 11)))),
5)
- *)
or to annotate leaves: