# What are the differences between lenses and zippers?

This is an example of using a zipper in Haskell:

``````data Tree a = Fork (Tree a) (Tree a) | Leaf a
data Cxt a = Top | L (Cxt a) (Tree a) | R (Tree a) (Cxt a)
type Loc a = (Tree a, Cxt a)

left :: Loc a -> Loc a
left (Fork l r, c) = (l, L c r)

right :: Loc a -> Loc a
right (Fork l r, c) = (r, R l c)

top :: Tree a -> Loc a
top t = (t, Top)

up :: Loc a -> Loc a
up (t, L c r) = (Fork t r, c)
up (t, R l c) = (Fork l t, c)

upmost :: Loc a -> Loc a
upmost [email protected](t, Top) = l
upmost l = upmost (up l)

modify :: Loc a -> (Tree a -> Tree a) -> Loc a
modify (t, c) f = (f t, c)
```
```

This is an example of using a zipper in Clojure:

``````(use 'clojure.zip)
(require '[clojure.zip :as z])

user> (def z [[1 2 3] [4 [5 6] 7] [8 9]])
#'user/z

user> (def zp (zipper vector? seq (fn [_ c] c) z))
#'user/zp

user> zp
[[[1 2 3] [4 [5 6] 7] [8 9]] nil]

user> (-> zp down)
[[1 2 3] {:l [], :pnodes [[[1 2 3] [4 [5 6] 7] [8 9]]], :ppath nil, :r ([4 [5 6] 7] [8 9])}]

user> (first (-> zp down))
[1 2 3]
```
```

This is an example of using a Lens in Haskell:

``````data Person = P { name :: String
}
data Address = A { street :: String
, city :: String
, postcode :: String
}

setPostcode :: String -> Person -> Person
setPostcode pc p = p { addr = addr p { postcode = pc }}
```
```

This is an example of using a Lens in Clojure.

``````(use 'lens)

(def -postcode (mklens :postcode))
(def -city (mklens :city))
(def -street (mklens :street))
(def -age (mklens :age))
(def -name (mklens :name))
(def -uid (mklens :uid))
(def -identity (mklens :identity))

(-get -postcode home)

(-set -postcode home 500)
```
```

Now it seems both lenses and zippers are functional ways of traversing nested data structures.

My question is: What are the differences between lenses and zippers? Is one suited to a particular use case?

Zippers are akin to cursors: they allow to traverse trees in an ordered manner. Their usual operations are `up`, `down`, `left`, `right` and `edit`. (names may vary depending on impl)

Lenses are some sort of generalized keys (as in "keys of an associative datastructure"). The structure does not need to be ordered. Their usual operations are `fetch` and `putback` and are very similar to `get` and `assoc`. (names may vary depending on impl)

So as you see zippers are very much concerned about hierarchy (up/down) and order (left/right) while lenses are just about focusing (hence the name) on a piece of data, which may even be a projection (that is something that didn't existed on its own in the original structure).

For example in my ongoing work on Enliven, I have lenses that allow me to focus on a single class or style attribute in a HTML document.