fix manip trees
[lambda.git] / manipulating_trees_with_monads.mdwn
index 81dc451..c92065c 100644 (file)
@@ -164,14 +164,12 @@ result:
 Now that we have a tree transformer that accepts a reader monad as a
 parameter, we can see what it would take to swap in a different monad.
 
-<!-- FIXME -->
-
-For instance, we can use a state monad to count the number of nodes in
+For instance, we can use a state monad to count the number of leaves in
 the tree.
 
        type 'a state = int -> 'a * int;;
        let state_unit a = fun s -> (a, s);;
-       let state_bind_and_count u f = fun s -> let (a, s') = u s in f a (s' + 1);;
+       let state_bind u f = fun s -> let (a, s') = u s in f a s';;
 
 Gratifyingly, we can use the `tree_monadize` function without any
 modification whatsoever, except for replacing the (parametric) type
@@ -179,16 +177,16 @@ modification whatsoever, except for replacing the (parametric) type
 
        let rec tree_monadize (f : 'a -> 'b state) (t : 'a tree) : 'b tree state =
            match t with
-           | Leaf i -> state_bind_and_count (f i) (fun i' -> state_unit (Leaf i'))
-           | Node (l, r) -> state_bind_and_count (tree_monadize f l) (fun x ->
-                              state_bind_and_count (tree_monadize f r) (fun y ->
+           | Leaf i -> state_bind (f i) (fun i' -> state_unit (Leaf i'))
+           | Node (l, r) -> state_bind (tree_monadize f l) (fun x ->
+                              state_bind (tree_monadize f r) (fun y ->
                                 state_unit (Node (x, y))));;
 
-Then we can count the number of nodes in the tree:
+Then we can count the number of leaves in the tree:
 
-       # tree_monadize state_unit t1 0;;
+       # tree_monadize (fun a s -> (a, s+1)) t1 0;;
        - : int tree * int =
-       (Node (Node (Leaf 2, Leaf 3), Node (Leaf 5, Node (Leaf 7, Leaf 11))), 13)
+       (Node (Node (Leaf 2, Leaf 3), Node (Leaf 5, Node (Leaf 7, Leaf 11))), 5)
        
            .
         ___|___
@@ -201,17 +199,6 @@ Then we can count the number of nodes in the tree:
                |  |
                7  11
 
-Notice that we've counted each internal node twice---it's a good
-exercise to adjust the code to count each node once.
-
-<!--
-A tree with n leaves has 2n - 1 nodes.
-This function will currently return n*1 + (n-1)*2 = 3n - 2.
-To convert b = 3n - 2 into 2n - 1, we can use: let n = (b + 2)/3 in 2*n -1
-
-But I assume Chris means here, adjust the code so that no corrections of this sort have to be applied.
--->
-
 
 One more revealing example before getting down to business: replacing
 `state` everywhere in `tree_monadize` with `list` gives us
@@ -227,7 +214,7 @@ from some input to a result, this transformer replaces each `int` with
 a list of `int`'s.
 
 <!--
-We don't make it clear why the fun has to be int -> int list list, instead of int -> int list
+FIXME: We don't make it clear why the fun has to be int -> int list list, instead of int -> int list
 -->
 
 
@@ -252,8 +239,6 @@ We then compute:
        # tree_monadize (fun a k -> a :: (k a)) t1 (fun t -> []);;
        - : int list = [2; 3; 5; 7; 11]
 
-<!-- FIXME: what if we had fun t -> [-t]? why `t`? -->
-
 We have found a way of collapsing a tree into a list of its leaves.
 
 The continuation monad is amazingly flexible; we can use it to
@@ -290,6 +275,9 @@ generalizing the type of the continuation monad to
 
        type ('a, 'b, 'c) continuation = ('a -> 'b) -> 'c;;
 
+If you want to see how to parameterize the definition of the `tree_monadize` function, so that you don't have to keep rewriting it for each new monad, see [this code](/code/tree_monadize.ml).
+
+
 The binary tree monad
 ---------------------