Search code examples
functional-programmingocaml

TreeZipper next operation with _ vs with full match expression


Let the following be the tree zipper:

type 'a ntree = Node of 'a * 'a ntree list

type 'a context =
  | Top
  | Context of 'a ntree list * 'a * 'a context * 'a ntree list

type 'a tree_zipper = TZ of 'a context * 'a ntree

let tz1 = TZ (Context (
                [Node ("*", [Node ("a", []); Node ("b", [])])],  (*left siblings in reverse order *)
                "+", (*value of parent node *)
                Top, (*parent's context *)
                []), (*right sibling in order *)
              Node ("*", [Node ("c", []); Node ("d", [])]));;

What is the difference between this next operation (mine):

let next_exn (TZ (c, t)) = (* on the right, not possible when context is top or right = []*)
  match c with
  | Top -> failwith "right of top node"
  | Context (left, v, up, []) -> failwith "right of last child" (*explain*)
  | Context (left, v, up, r::right) -> TZ (Context (t::left, v, up, right), r)

and the provided solution:

let next_exn (TZ (c, t)) = (* on the right, not possible when context is top or right = []*)
  match c with
  | Top -> failwith "right of top node"
  | Context(left, v, up, r::right) -> TZ (Context(t::left, v, up, right), r)
  | _ -> failwith "right of last child"

I assume they are the same, but I might be missing something.

Also, why we set the left siblings list in down_exn to [] in:

let down_exn (TZ (c, t)) = 
  match t with (* go to first child *)
  | Node (_, []) -> failwith "down of leaf"
  | Node (v, d::ds) -> TZ (Context([], v, c, ds), d)

?


Solution

  • Yes, the two are effectively equivalent. When reordering patterns in match expressions, remember that it will evaluate the corresponding expression for the first pattern that matches.

    It's a matter of opinion, but I certainly prefer to have the simplest outcomes (including exceptions or recursion base cases) before more complex outcomes. Based on reading a lot of code, I suspect I'm not alone in that preference.

    As for your second question, if we go "down", we are going "down" to the left-most node, so there cannot be sibling nodes to the left.