Haskell Language Lens and Prism


Example

A Lens' s a means that you can always find an a within any s. A Prism' s a means that you can sometimes find that s actually just is a but sometimes it's something else.

To be more clear, we have _1 :: Lens' (a, b) a because any tuple always has a first element. We have _Just :: Prism' (Maybe a) a because sometimes Maybe a is actually an a value wrapped in Just but sometimes it's Nothing.

With this intuition, some standard combinators can be interpreted parallel to one another

  • view :: Lens' s a -> (s -> a) "gets" the a out of the s
  • set :: Lens' s a -> (a -> s -> s) "sets" the a slot in s
  • review :: Prism' s a -> (a -> s) "realizes" that an a could be an s
  • preview :: Prism' s a -> (s -> Maybe a) "attempts" to turn an s into an a.

Another way to think about it is that a value of type Lens' s a demonstrates that s has the same structure as (r, a) for some unknown r. On the other hand, Prism' s a demonstrates that s has the same structure as Either r a for some r. We can write those four functions above with this knowledge:

-- `Lens' s a` is no longer supplied, instead we just *know* that `s ~ (r, a)`

view :: (r, a) -> a
view (r, a) = a

set :: a -> (r, a) -> (r, a)
set a (r, _) = (r, a)

-- `Prism' s a` is no longer supplied, instead we just *know* that `s ~ Either r a`

review :: a -> Either r a
review a = Right a

preview :: Either r a -> Maybe a
preview (Left _) = Nothing
preview (Right a) = Just a