Portability  Rank2Types 

Stability  provisional 
Maintainer  Edward Kmett <ekmett@gmail.com> 
Safe Haskell  Trustworthy 
A
is just any function Getter
s a(s > a)
, which we've flipped
into continuation passing style, (a > r) > s > r
and decorated
with Accessor
to obtain:
typeGetting
r s t a b = (a >Accessor
r b) > s >Accessor
r t
If we restrict access to knowledge about the type r
and can work for
any b and t, we could get:
typeGetter
s a = forall r.Getting
r s s a a
But we actually hide the use of Accessor
behind a class Gettable
to error messages from type class resolution rather than at unification
time, where they are much uglier.
typeGetter
s a = forall f.Gettable
f => (a > f a) > s > f s
Everything you can do with a function, you can do with a Getter
, but
note that because of the continuation passing style (.
) composes them
in the opposite order.
Since it is only a function, every Getter
obviously only retrieves a
single value for a given input.
 type Getter s a = forall f. Gettable f => (a > f a) > s > f s
 type Getting r s t a b = (a > Accessor r b) > s > Accessor r t
 to :: (s > a) > Getter s a
 (^.) :: s > Getting a s t a b > a
 (^$) :: Getting a s t a b > s > a
 (&) :: a > (a > b) > b
 (^&) :: a > (a > b) > b
 view :: MonadReader s m => Getting a s t a b > m a
 views :: MonadReader s m => Getting r s t a b > (a > r) > m r
 use :: MonadState s m => Getting a s t a b > m a
 uses :: MonadState s m => Getting r s t a b > (a > r) > m r
 view' :: MonadReader s m => Getting a s s a a > m a
 views' :: MonadReader s m => Getting r s s a a > (a > r) > m r
 use' :: MonadState s m => Getting a s s a a > m a
 uses' :: MonadState s m => Getting r s s a a > (a > r) > m r
 newtype ReifiedGetter s a = ReifyGetter {
 reflectGetter :: Getter s a
 class Functor f => Gettable f
 data Accessor r a
Getters
type Getter s a = forall f. Gettable f => (a > f a) > s > f sSource
A Getter
describes how to retrieve a single value in a way that can be
composed with other lenslike constructions.
Unlike a Lens
a Getter
is readonly. Since a Getter
cannot be used to write back there are no lens laws that can be applied to
it. In fact, it is isomorphic to an arbitrary function from (a > s)
.
Moreover, a Getter
can be used directly as a Fold
,
since it just ignores the Applicative
.
type Getting r s t a b = (a > Accessor r b) > s > Accessor r tSource
When you see this in a type signature it indicates that you can
pass the function a Lens
, Getter
,
Traversal
, Fold
,
Prism
, Iso
, or one of
the indexed variants, and it will just "do the right thing".
Most Getter
combinators are able to be used with both a Getter
or a
Fold
in limited situations, to do so, they need to be
monomorphic in what we are going to extract with Const
. To be compatible
with Lens
, Traversal
and
Iso
we also restricted choices of the irrelevant t
and
b
parameters.
If a function accepts a
, then when Getting
r s t a br
is a Monoid
, then
you can pass a Fold
(or
Traversal
), otherwise you can only pass this a
Getter
or Lens
.
Building Getters
Combinators for Getters and Folds
(^.) :: s > Getting a s t a b > aSource
View the value pointed to by a Getter
or Lens
or the
result of folding over all the results of a Fold
or
Traversal
that points at a monoidal values.
This is the same operation as view
with the arguments flipped.
The fixity and semantics are such that subsequent field accesses can be
performed with (.
)
>>>
(a,b)^._2
b
>>>
("hello","world")^._2
"world"
>>>
import Data.Complex
>>>
((0, 1 :+ 2), 3)^._1._2.to magnitude
2.23606797749979
(^.
) :: s >Getter
s a > a (^.
) ::Monoid
m => s >Fold
s m > m (^.
) :: s >Simple
Iso
s a > a (^.
) :: s >Simple
Lens
s a > a (^.
) ::Monoid
m => s >Simple
Traversal
s m > m
(^$) :: Getting a s t a b > s > aSource
View the value pointed to by a Getter
, Iso
or
Lens
or the result of folding over all the results of a
Fold
or Traversal
that points
at a monoidal values.
This is the same operation as view
, only infix.
to
f^$
x ≡ f x
>>>
to f ^$ x
f x
>>>
_2 ^$ (1, "hello")
"hello"
(^$
) ::Getter
s a > s > a (^$
) ::Monoid
m =>Fold
s m > s > m (^$
) ::Simple
Iso
s a > s > a (^$
) ::Simple
Lens
s a > s > a (^$
) ::Monoid
m =>Simple
Traversal
s m > s > m
(&) :: a > (a > b) > bSource
Passes the result of the left side to the function on the right side (forward pipe operator).
This is the flipped version of ($
), which is more common in languages like F# as (>
) where it is needed
for inference. Here it is supplied for notational convenience and given a precedence that allows it
to be nested inside uses of ($
).
>>>
a & f
f a
>>>
"hello" & length & succ
6
This combinator is commonly used when applying multiple lens operations in sequence.
>>>
("hello","world") & _1.element 0 .~ 'j' & _1.element 4 .~ 'y'
("jelly","world")
This reads somewhat similar to:
>>>
flip execState ("hello","world") $ do _1.element 0 .= 'j'; _1.element 4 .= 'y'
("jelly","world")
view :: MonadReader s m => Getting a s t a b > m aSource
View the value pointed to by a Getter
, Iso
or
Lens
or the result of folding over all the results of a
Fold
or Traversal
that points
at a monoidal values.
view
.to
≡id
>>>
view (to f) a
f a
>>>
view _2 (1,"hello")
"hello"
>>>
view (to succ) 5
6
>>>
view (_2._1) ("hello",("world","!!!"))
"world"
As views
is commonly used to access the target of a Getter
or obtain a monoidal summary of the targets of a Fold
,
It may be useful to think of it as having one of these more restrictive signatures:
view
::Getter
s a > s > aview
::Monoid
m =>Fold
s m > s > mview
::Simple
Iso
s a > s > aview
::Simple
Lens
s a > s > aview
::Monoid
m =>Simple
Traversal
s m > s > m
In a more general setting, such as when working with a monad transformer stack you can use:
view
::MonadReader
s m =>Getter
s a > m aview
:: (MonadReader
s m,Monoid
a) =>Fold
s a > m aview
::MonadReader
s m =>Simple
Iso
s a > m aview
::MonadReader
s m =>Simple
Lens
s a > m aview
:: (MonadReader
s m,Monoid
a) =>Simple
Traversal
s a > m a
views :: MonadReader s m => Getting r s t a b > (a > r) > m rSource
View the value of a Getter
, Iso
,
Lens
or the result of folding over the result of mapping
the targets of a Fold
or
Traversal
.
It may be useful to think of views
as having these more restrictive
signatures:
views
l f ≡view
(l.
to
f)
>>>
views (to f) g a
g (f a)
>>>
views _2 length (1,"hello")
5
As views
is commonly used to access the target of a Getter
or obtain a monoidal summary of the targets of a Fold
,
It may be useful to think of it as having one of these more restrictive signatures:
views
::Getter
s a > (a > r) > s > rviews
::Monoid
m =>Fold
s a > (a > m) > s > mviews
::Simple
Iso
s a > (a > r) > s > rviews
::Simple
Lens
s a > (a > r) > s > rviews
::Monoid
m =>Simple
Traversal
s a > (a > m) > s > m
In a more general setting, such as when working with a monad transformer stack you can use:
view
::MonadReader
s m =>Getter
s a > m aview
:: (MonadReader
s m,Monoid
a) =>Fold
s a > m aview
::MonadReader
s m =>Simple
Iso
s a > m aview
::MonadReader
s m =>Simple
Lens
s a > m aview
:: (MonadReader
s m,Monoid
a) =>Simple
Traversal
s a > m a
use :: MonadState s m => Getting a s t a b > m aSource
Use the target of a Lens
, Iso
, or
Getter
in the current state, or use a summary of a
Fold
or Traversal
that points
to a monoidal value.
>>>
evalState (use _1) (a,b)
a
>>>
evalState (use _1) ("hello","world")
"hello"
use
::MonadState
s m =>Getter
s a > m ause
:: (MonadState
s m,Monoid
r) =>Fold
s r > m ruse
::MonadState
s m =>Simple
Iso
s a > m ause
::MonadState
s m =>Simple
Lens
s a > m ause
:: (MonadState
s m,Monoid
r) =>Simple
Traversal
s r > m r
uses :: MonadState s m => Getting r s t a b > (a > r) > m rSource
Use the target of a Lens
, Iso
or
Getter
in the current state, or use a summary of a
Fold
or Traversal
that
points to a monoidal value.
>>>
evalState (uses _1 length) ("hello","world")
5
uses
::MonadState
s m =>Getter
s a > (a > r) > m ruses
:: (MonadState
s m,Monoid
r) =>Fold
s a > (a > r) > m ruses
::MonadState
s m =>Simple
Lens
s a > (a > r) > m ruses
::MonadState
s m =>Simple
Iso
s a > (a > r) > m ruses
:: (MonadState
s m,Monoid
r) =>Simple
Traversal
s a > (a > r) > m r
Simple Getter Operations
view' :: MonadReader s m => Getting a s s a a > m aSource
This is a type restricted version of view
that expects a Simple
Getter
.
View the value pointed to by a Getter
, Iso
or
Lens
or the result of folding over all the results of a
Fold
or Traversal
that points
at a monoidal values.
view'
.to
≡id
>>>
view' (to f) a
f a
>>>
view' _2 (1,"hello")
"hello"
>>>
view' (to succ) 5
6
>>>
view' (_2._1) ("hello",("world","!!!"))
"world"
As view'
is commonly used to access the target of a Getter
or obtain a monoidal summary of the targets of a Fold
,
It may be useful to think of it as having one of these more restrictive signatures:
view'
::Getter
s a > s > aview'
::Monoid
m =>Fold
s m > s > mview'
::Simple
Iso
s a > s > aview'
::Simple
Lens
s a > s > aview'
::Monoid
m =>Simple
Traversal
s m > s > m
In a more general setting, such as when working with a monad transformer stack you can use:
view'
::MonadReader
s m =>Getter
s a > m aview'
:: (MonadReader
s m,Monoid
a) =>Fold
s a > m aview'
::MonadReader
s m =>Simple
Iso
s a > m aview'
::MonadReader
s m =>Simple
Lens
s a > m aview'
:: (MonadReader
s m,Monoid
a) =>Simple
Traversal
s a > m a
views' :: MonadReader s m => Getting r s s a a > (a > r) > m rSource
This is a type restricted version of views
that expects a Simple
Getter
.
View the value of a Getter
, Iso
,
Lens
or the result of folding over the result of mapping
the targets of a Fold
or
Traversal
.
It may be useful to think of perviews
as having these more restrictive
signatures:
views'
l f ≡view'
(l.
to
f)
>>>
views' _2 length (1,"hello")
5
As views'
is commonly used to access the target of a Getter
or obtain a monoidal summary of the targets of a Fold
,
It may be useful to think of it as having one of these more restrictive signatures:
views'
::Getter
s a > (a > r) > s > rviews'
::Monoid
m =>Fold
s a > (a > m) > s > mviews'
::Simple
Iso
s a > (a > r) > s > rviews'
::Simple
Lens
s a > (a > r) > s > rviews'
::Monoid
m =>Simple
Traversal
s a > (a > m) > s > m
In a more general setting, such as when working with a monad transformer stack you can use:
views'
::MonadReader
s m =>Getter
s a > (a > r) > m rviews'
:: (MonadReader
s m,Monoid
a) =>Fold
s a > (a > r) > m rviews'
::MonadReader
s m =>Simple
Iso
s a > (a > r) > m rviews'
::MonadReader
s m =>Simple
Lens
s a > (a > r) > m rviews'
:: (MonadReader
s m,Monoid
a) =>Simple
Traversal
s a > (a > r) > m r
use' :: MonadState s m => Getting a s s a a > m aSource
This is a type restricted version of use
that expects a Simple
Getter
.
Use the target of a Simple
Lens
, Iso
, or
Getter
in the current state, or use a summary of a
Fold
or Traversal
that points
to a monoidal value.
This use of this combinator may aid typeinference when working with lenses or traversals that have nondefaultable typeclass constraints on their arguments.
>>>
evalState (use' _1) (a,b)
a
>>>
evalState (use' _1) ("hello","world")
"hello"
use'
::MonadState
s m =>Getter
s a > m ause'
:: (MonadState
s m,Monoid
r) =>Fold
s r > m ruse'
::MonadState
s m =>Simple
Iso
s a > m ause'
::MonadState
s m =>Simple
Lens
s a > m ause'
:: (MonadState
s m,Monoid
r) =>Simple
Traversal
s r > m r
uses' :: MonadState s m => Getting r s s a a > (a > r) > m rSource
This is a type restricted version of uses
that expects a Simple
Getter
.
Use the target of a Lens
, Iso
or
Getter
in the current state, or use a summary of a
Fold
or Traversal
that
points to a monoidal value.
>>>
evalState (uses' _1 length) ("hello","world")
5
uses'
::MonadState
s m =>Getter
s a > (a > r) > m ruses'
:: (MonadState
s m,Monoid
r) =>Fold
s a > (a > r) > m ruses'
::MonadState
s m =>Simple
Lens
s a > (a > r) > m ruses'
::MonadState
s m =>Simple
Iso
s a > (a > r) > m ruses'
:: (MonadState
s m,Monoid
r) =>Simple
Traversal
s a > (a > r) > m r
Storing Getters
newtype ReifiedGetter s a Source
Useful for storing getters in containers.
ReifyGetter  

class Functor f => Gettable f Source
Generalizing Const
so we can apply simple Applicative
transformations to it and so we can get nicer error messages
A Gettable
Functor
ignores its argument, which it carries solely as a
phantom type parameter.
To ensure this, an instance of Gettable
is required to satisfy:
id
=fmap
f =coerce
Which is equivalent to making a
an "anyvariant" functor.
Gettable
f