Lenses
Usage
{# LANGUAGE TemplateHaskell #}
data Person = Person
{ _firstname :: String
, _surname :: String
}
 building lenses for _firstname and _surname
makeLenses ''Person
 create an HasPerson class with the `firstname` and `surname` optics
makeClassy ''Person
 create an HasFirstname and HasSurname class
data Person = Person
{ _PersonFirstname :: String
, _PersonSurname :: String
}
makeField ''Person
Lens
A lens is a firstclass reference to a subpart of some data type.
Lens' s a
operates on a container s
and put the focus on 'a'.
Lens' s t a b
when you replace a
in s
with b
, its type changes to t
.
Note that lenses are not accessors
but focusers
. It focus on a particular location of a structure. These are the types we want for view
, set
and over/update
:
view :: Lens' s a > s > a
set :: Lens' s a > a > s > s
over :: Lens' s a > (a > a) > s > s
The big insight is the fact that the Lens'
type can be implemented as an unique type that works for all 3 methods (given we add a functor constraint). It is actually a type synonym for:
type Lens' s a = forall f. Functor f => (a > f a) > s > f s (1)
1  This is a kind of a lifting from the element (a → f a) to the container (s → f s) 
Lenses form a category where . is composition and id is the identity.

> over _1 (++ "!!!") ("goal", "the crowd goes wild") > ("goal", "the crowd goes wild") & _1 %~ (<> "!!!") (1) ("goal!!!", "the crowd goes wild") > ("world", "world") & _1 .~ "hello" & _2 .~ "hello" (1) > ([1], 2) & _1 <>~ [2,3,4]
1  & allows to start the expression from s and then compose.
It is defined as the reverse of $ operator. 
Common operators
^. 
view 
^? 
preview 
^.. 
toListOf 
.~ 
set 
%~ 
over 
<>~ 
apply the func '<>' 
.= 
state monad view 
Traverse
Traversals are Lenses which focus on multiple targets simultaneously. We actually don’t know how many targets they might be focusing on: it could be exactly 1 (like a Lens) or maybe 0 (like a Prism) or several. In that regard, a traversal is a like a Lens' except weaker (more general):
type Traversal' a b =
forall f . (Applicative f) => (b > f b) > (a > f a)
firstOf/lastOf traverse :: Traversable t => t a > Maybe a
> firstOf traverse [1,2,3]
1
> [1..8] & lastOf traverse
8
toListOf (^..)

view list of targets
preview (^?)

like
view
for Prism’s or Traversal’s. It handles access that focuses on either 0 or 1 targets.
Prims
Prisms are kind of like Lenses that can fail or miss.
Note how the monoid instance of String allows us to get a native String from this expression:
> s = (Left "hello", 5) > s ^. _1._Left "hello" > s ^. _1._Right ""
But without a monoid instance it cannot work and the (^?)
is necessary:
> s = (Left 5, 5)
> s ^? _1._Left
Just 5
> s ^? _1._Right
Nothing
> :t preview _Right (Right 1)
Num b => Maybe b