Skip to content

Instantly share code, notes, and snippets.

@regiskuckaertz
Last active March 22, 2017 13:50
Show Gist options
  • Save regiskuckaertz/e659edb44c8208aac0749cdbe6718121 to your computer and use it in GitHub Desktop.
Save regiskuckaertz/e659edb44c8208aac0749cdbe6718121 to your computer and use it in GitHub Desktop.
Zipper for a DOM-like tree data type
data Tree a = Leaf a | Node a [Tree]
type Crumb a = (a, [Tree a], [Tree a])
type Breadcrumbs a = [Crumb a]
type Zipper a = (Tree a, Breadcrumbs a)
goDown :: Zipper a -> Int -> Zipper a
goDown (Node el children, bs) n = let (head, nth:tail) = splitAt children n
in (nth, Crumb el head tail : bs)
goUp :: Zipper a -> Zipper a
goUp node (parent, left, right):bs = (Node parent (left ++ [node] ++ right), bs)
modify :: (a -> a) -> Zipper a -> Zipper a
modify f (Node x l r, bs) = (Node (f x) l r, bs)
modify f (Leaf x, bs) = (Leaf (f x), bs)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment