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. (Contravariant f, Functor f) => (a > f a) > s > f s
 type IndexedGetter i s a = forall p f. (Indexable i p, Contravariant f, Functor f) => p a (f a) > s > f s
 type Getting r s a = (a > Accessor r a) > s > Accessor r s
 type IndexedGetting i m s a = Indexed i a (Accessor m a) > s > Accessor m s
 type Accessing p m s a = p a (Accessor m a) > s > Accessor m s
 to :: (s > a) > IndexPreservingGetter s a
 (^.) :: s > Getting a s a > a
 view :: MonadReader s m => Getting a s a > m a
 views :: (Profunctor p, MonadReader s m) => Overloading p (>) (Accessor r) s s a a > p a r > m r
 use :: MonadState s m => Getting a s a > m a
 uses :: (Profunctor p, MonadState s m) => Overloading p (>) (Accessor r) s s a a > p a r > m r
 listening :: MonadWriter w m => Getting u w u > m a > m (a, u)
 listenings :: MonadWriter w m => Getting v w u > (u > v) > m a > m (a, v)
 (^@.) :: s > IndexedGetting i (i, a) s a > (i, a)
 iview :: MonadReader s m => IndexedGetting i (i, a) s a > m (i, a)
 iviews :: MonadReader s m => IndexedGetting i r s a > (i > a > r) > m r
 iuse :: MonadState s m => IndexedGetting i (i, a) s a > m (i, a)
 iuses :: MonadState s m => IndexedGetting i r s a > (i > a > r) > m r
 ilistening :: MonadWriter w m => IndexedGetting i (i, u) w u > m a > m (a, (i, u))
 ilistenings :: MonadWriter w m => IndexedGetting i v w u > (i > u > v) > m a > m (a, v)
 class Contravariant f where
 contramap :: (a > b) > f b > f a
 coerce :: (Contravariant f, Functor f) => f a > f b
 coerced :: (Functor f, Contravariant f) => LensLike f s t a b > LensLike' f s a
 newtype Accessor r a = Accessor {
 runAccessor :: r
 class (Contravariant f, Functor f) => Gettable f
Getters
type Getter s a = forall f. (Contravariant f, Functor 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 IndexedGetter i s a = forall p f. (Indexable i p, Contravariant f, Functor f) => p a (f a) > s > f sSource
Every IndexedGetter
is a valid IndexedFold
and can be used for Getting
like a Getter
.
type Getting r s a = (a > Accessor r a) > s > Accessor r sSource
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
.
type IndexedGetting i m s a = Indexed i a (Accessor m a) > s > Accessor m sSource
Used to consume an IndexedFold
.
type Accessing p m s a = p a (Accessor m a) > s > Accessor m sSource
This is a convenient alias used when consuming (indexed) getters and (indexed) folds in a highly general fashion.
Building Getters
to :: (s > a) > IndexPreservingGetter s aSource
Combinators for Getters and Folds
(^.) :: s > Getting a s a > 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 >Iso'
s a > a (^.
) :: s >Lens'
s a > a (^.
) ::Monoid
m => s >Traversal'
s m > m
view :: MonadReader s m => Getting a s a > 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 value.
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 restricted signatures:
view
::Getter
s a > s > aview
::Monoid
m =>Fold
s m > s > mview
::Iso'
s a > s > aview
::Lens'
s a > s > aview
::Monoid
m =>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 =>Iso'
s a > m aview
::MonadReader
s m =>Lens'
s a > m aview
:: (MonadReader
s m,Monoid
a) =>Traversal'
s a > m a
views :: (Profunctor p, MonadReader s m) => Overloading p (>) (Accessor r) s s a a > p a r > m rSource
View a function of the value pointed to by a Getter
or Lens
or the result of
folding over the result of mapping the targets of a Fold
or
Traversal
.
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 restricted signatures:
views
::Getter
s a > (a > r) > s > rviews
::Monoid
m =>Fold
s a > (a > m) > s > mviews
::Iso'
s a > (a > r) > s > rviews
::Lens'
s a > (a > r) > s > rviews
::Monoid
m =>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 =>Iso'
s a > m aview
::MonadReader
s m =>Lens'
s a > m aview
:: (MonadReader
s m,Monoid
a) =>Traversal'
s a > m a
views
::MonadReader
s m =>Getting
r s a > (a > r) > m r
use :: MonadState s m => Getting a s a > 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 =>Iso'
s a > m ause
::MonadState
s m =>Lens'
s a > m ause
:: (MonadState
s m,Monoid
r) =>Traversal'
s r > m r
uses :: (Profunctor p, MonadState s m) => Overloading p (>) (Accessor r) s s a a > p 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 =>Lens'
s a > (a > r) > m ruses
::MonadState
s m =>Iso'
s a > (a > r) > m ruses
:: (MonadState
s m,Monoid
r) =>Traversal'
s a > (a > r) > m r
uses
::MonadState
s m =>Getting
r s t a b > (a > r) > m r
listening :: MonadWriter w m => Getting u w u > m a > m (a, u)Source
This is a generalized form of listen
that only extracts the portion of
the log that is focused on by a Getter
. If given a Fold
or a Traversal
then a monoidal summary of the parts of the log that are visited will be
returned.
listening
::MonadWriter
w m =>Getter
w u > m a > m (a, u)listening
::MonadWriter
w m =>Lens'
w u > m a > m (a, u)listening
::MonadWriter
w m =>Iso'
w u > m a > m (a, u)listening
:: (MonadWriter
w m,Monoid
u) =>Fold
w u > m a > m (a, u)listening
:: (MonadWriter
w m,Monoid
u) =>Traversal'
w u > m a > m (a, u)listening
:: (MonadWriter
w m,Monoid
u) =>Prism'
w u > m a > m (a, u)
listenings :: MonadWriter w m => Getting v w u > (u > v) > m a > m (a, v)Source
This is a generalized form of listen
that only extracts the portion of
the log that is focused on by a Getter
. If given a Fold
or a Traversal
then a monoidal summary of the parts of the log that are visited will be
returned.
listenings
::MonadWriter
w m =>Getter
w u > (u > v) > m a > m (a, v)listenings
::MonadWriter
w m =>Lens'
w u > (u > v) > m a > m (a, v)listenings
::MonadWriter
w m =>Iso'
w u > (u > v) > m a > m (a, v)listenings
:: (MonadWriter
w m,Monoid
v) =>Fold
w u > (u > v) > m a > m (a, v)listenings
:: (MonadWriter
w m,Monoid
v) =>Traversal'
w u > (u > v) > m a > m (a, v)listenings
:: (MonadWriter
w m,Monoid
v) =>Prism'
w u > (u > v) > m a > m (a, v)
Indexed Getters
Indexed Getter Combinators
(^@.) :: s > IndexedGetting i (i, a) s a > (i, a)Source
View the value pointed to by a Getter
or Lens
.
This is the same operation as iview
with the arguments flipped.
The fixity and semantics are such that subsequent field accesses can be
performed with (.
).
>>>
(a,b,c,d)^@._2
(1,b)
>>>
("hello","world","!!!")^@._2
(1,"world")
(^@.
) :: s >IndexedGetter
i s a > (i, a) (^@.
) :: s >IndexedLens'
i s a > (i, a)
The result probably doesn't have much meaning when applied to an IndexedFold
.
iview :: MonadReader s m => IndexedGetting i (i, a) s a > m (i, a)Source
View the index and value of an IndexedGetter
into the current environment as a pair.
When applied to an IndexedFold
the result will most likely be a nonsensical monoidal summary of
the indices tupled with a monoidal summary of the values and probably not whatever it is you wanted.
iviews :: MonadReader s m => IndexedGetting i r s a > (i > a > r) > m rSource
View a function of the index and value of an IndexedGetter
into the current environment.
When applied to an IndexedFold
the result will be a monoidal summary instead of a single answer.
iviews
≡ifoldMapOf
iuse :: MonadState s m => IndexedGetting i (i, a) s a > m (i, a)Source
Use the index and value of an IndexedGetter
into the current state as a pair.
When applied to an IndexedFold
the result will most likely be a nonsensical monoidal summary of
the indices tupled with a monoidal summary of the values and probably not whatever it is you wanted.
iuses :: MonadState s m => IndexedGetting i r s a > (i > a > r) > m rSource
Use a function of the index and value of an IndexedGetter
into the current state.
When applied to an IndexedFold
the result will be a monoidal summary instead of a single answer.
ilistening :: MonadWriter w m => IndexedGetting i (i, u) w u > m a > m (a, (i, u))Source
This is a generalized form of listen
that only extracts the portion of
the log that is focused on by a Getter
. If given a Fold
or a Traversal
then a monoidal summary of the parts of the log that are visited will be
returned.
ilistening
::MonadWriter
w m =>IndexedGetter
i w u > m a > m (a, (i, u))ilistening
::MonadWriter
w m =>IndexedLens'
i w u > m a > m (a, (i, u))ilistening
:: (MonadWriter
w m,Monoid
u) =>IndexedFold
i w u > m a > m (a, (i, u))ilistening
:: (MonadWriter
w m,Monoid
u) =>IndexedTraversal'
i w u > m a > m (a, (i, u))
ilistenings :: MonadWriter w m => IndexedGetting i v w u > (i > u > v) > m a > m (a, v)Source
This is a generalized form of listen
that only extracts the portion of
the log that is focused on by a Getter
. If given a Fold
or a Traversal
then a monoidal summary of the parts of the log that are visited will be
returned.
ilistenings
::MonadWriter
w m =>IndexedGetter
w u > (i > u > v) > m a > m (a, v)ilistenings
::MonadWriter
w m =>IndexedLens'
w u > (i > u > v) > m a > m (a, v)ilistenings
:: (MonadWriter
w m,Monoid
v) =>IndexedFold
w u > (i > u > v) > m a > m (a, v)ilistenings
:: (MonadWriter
w m,Monoid
v) =>IndexedTraversal'
w u > (i > u > v) > m a > m (a, v)
Implementation Details
class Contravariant f where
Any instance should be subject to the following laws:
contramap id = id contramap f . contramap g = contramap (g . f)
Note, that the second law follows from the free theorem of the type of
contramap
and the first law, so you need only check that the former
condition holds.
contramap :: (a > b) > f b > f a
coerce :: (Contravariant f, Functor f) => f a > f bSource
This Generalizes Const
so we can apply simple Applicative
transformations to it and so we can get nicer error messages.
A Functor
you can coerce
ignores its argument, which it carries solely as a
phantom type parameter.
By the Functor
and Contravariant
laws, an instance of Gettable
will necessarily satisfy:
id
=fmap
f =coerce
=contramap
g
Used instead of Const
to report
No instance for (Settable
Accessor
)
when the user attempts to misuse a Setter
as a
Getter
, rather than a monolithic unification error.
Accessor  

class (Contravariant f, Functor f) => Gettable f Source
This class is provided mostly for backwards compatibility with lens 3.8, but it can also shorten type signatures.
(Contravariant f, Functor f) => Gettable f 