

Learn you a Haskell: Zippers - voxcogitatio
http://learnyouahaskell.com/zippers

======
jberryman
LYAH is great. For those who are interested, there is a library, 'syz' (Scrap
Your Zippers), which provides a generic zipper for any data type, even
mutually-recursive types:

[http://hackage.haskell.org/packages/archive/syz/0.2.0.0/doc/...](http://hackage.haskell.org/packages/archive/syz/0.2.0.0/doc/html/Data-
Generics-Zipper.html)

Its internals are pretty interesting if you've ever thought about implementing
a generic zipper structure. For example it uses Typeable to reify the focus
type.

I'm finishing up my own generic zipper library which I hope will be simpler
and more useful than syz.

------
eru
Here's a challenge: Design a zipper that works for cyclic graphs. There will
be 10 GBP for the winner's charity of choice. (jacquesm may give another 10
Euro in addition.)

(Hint: "Purely Functional Datastructures" solves this problem for graphs
shaped like a sigle ring. Perhaps this solution can be generalized?)

~~~
eru
Please post entries either to HN or send me an email. My address is in my
profile.

I can also give more details about rules and conditions, if needed.

P.S. Might as well make it 100 GBP for the first challenge. I am really
interested to see whether there's a solution that does it in O(1), like
zippers do. (Or alternatively a proof that O(1) to move from node to node is
not possible.)

~~~
copper
Wouldn't the Data.Graph.Inductive representation of a graph satisfy this (It
might not be O(1), but it's pretty close)? I must admit that I find it hard to
see what a zipper for a graph should look like, though.

~~~
eru
I know how to get a zipper for a static graph by Tying the Knot
(<http://haskell.org/haskellwiki/Tying_the_Knot>). But writing one where you
can add and remove nodes and edges seems much harder.

You already know how a zipper for a tree looks like. And you have probably
seen a functional queue. Generalizing from both of those, you can imagine how
a zipper would work.

I can write down the types and all, even if I don't know of any
implementation. But that's probably a topic for a blog post, or so.

~~~
copper
I think I understand that, but without actually writing it out, it's going to
be impossible to test.

The types I was talking about go as: type Context a b = (Adj b, Node, a, Adj
b) type Adj b = [(b, Node)]

It definitely allows traversal, and adding nodes seems to be possible, too
(judging from the api, of course, it ought to be :)

~~~
eru
From the types you give, I can't see how it works. Would you please elaborate?

------
jwr
Clojure also has a pretty neat zipper library in contrib. I've used it in
projects and I wish I had introductory material as great as this tutorial back
then.

------
jewbacca
I've had an investigation on the backburner for a while on whether there's a
zipper-like structure for representing 2D grids (eg, a game board). I feel
like this may be a blind alley, because a grid would have cycles and no
inherent ordering. Can anybody shed some light on this?

~~~
maxtilford
I think this blog post will be relevant:
[http://blog.sigfpe.com/2006/12/evaluating-cellular-
automata-...](http://blog.sigfpe.com/2006/12/evaluating-cellular-automata-
is.html)

------
grogers
Another good introduction to zippers that helped me understand them in plain
terms is: [http://blog.ezyang.com/2010/04/you-could-have-invented-
zippe...](http://blog.ezyang.com/2010/04/you-could-have-invented-zippers)

~~~
eru
And for those who like their math hard to understand (and rigorous): "The
Derivative of a Regular Type is its Type of One-Hole Contexts"
([http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.22.8...](http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.22.8611))

It's cited as "Conor's paper" in your article. But the link there doesn't
work.

