Skip to content

Instantly share code, notes, and snippets.

@nrolland
Created September 16, 2012 09:24
Show Gist options
  • Save nrolland/3731738 to your computer and use it in GitHub Desktop.
Save nrolland/3731738 to your computer and use it in GitHub Desktop.
zipper module
[<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
module Zipper =
let up z = match z.path with
| (d,v,other)::ep -> match d with
| TDirection.Left -> {focus=Branch(v,z.focus,other); path=ep}
| TDirection.Right -> {focus=Branch(v,other,z.focus); path=ep}
| [] -> failwith "can't go up" // because ep only goes down and is empty
let rec top z = match z.path with [] -> z | _ -> top (up z)
let left z = match z.focus with
| (Branch(v, l, r)) -> let v, explored, other = v, l, r
{focus=explored; path=((TDirection.Left, v, other)::z.path)}
| Leaf -> failwith "can't go down on leaf"
let right z = match z.focus with
| (Branch(v, l, r)) -> let v, explored, other = v, r, l
{focus=explored; path=((TDirection.Right, v, other)::z.path)}
| Leaf -> failwith "can't go down on leaf"
let rec move (p:ZDirection list) (z:'a Zipper) =
match p with
| [] -> z
| d::xs -> match d with
| Up -> move xs (up z)
| Left -> move xs (left z)
| Right -> move xs (right z)
let fromTree t = {focus = t; path = []}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment