Copyright | (C) 2012-14 Edward Kmett |
---|---|
License | BSD-style (see the file LICENSE) |
Maintainer | Edward Kmett <ekmett@gmail.com> |
Stability | provisional |
Portability | Rank2Types |
Safe Haskell | Trustworthy |
Language | Haskell98 |
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 Const
to obtain:
typeGetting
r s a = (a ->Const
r a) -> s ->Const
r s
If we restrict access to knowledge about the type r
, we could get:
typeGetter
s a = forall r.Getting
r s a
But we actually hide the use of Const
behind a class Gettable
to
report 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 -> Const r a) -> s -> Const r s
- type IndexedGetting i m s a = Indexed i a (Const m a) -> s -> Const m s
- type Accessing p m s a = p a (Const m a) -> s -> Const m s
- to :: (s -> a) -> IndexPreservingGetter s a
- ito :: (s -> (i, a)) -> IndexedGetter i s a
- (^.) :: s -> Getting a s a -> a
- view :: MonadReader s m => Getting a s a -> m a
- views :: (Profunctor p, MonadReader s m) => Optical p (->) (Const 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) => Optical p (->) (Const 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
- 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 Const a b :: * -> * -> * = Const {
- getConst :: a
- class (Contravariant f, Functor f) => Gettable f
Getters
type Getter s a = forall f. (Contravariant f, Functor f) => (a -> f a) -> s -> f s Source
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 read-only. 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 (s -> a)
.
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 s Source
Every IndexedGetter
is a valid IndexedFold
and can be used for Getting
like a Getter
.
type Getting r s a = (a -> Const r a) -> s -> Const r s Source
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 ar
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 (Const m a) -> s -> Const m s Source
Used to consume an IndexedFold
.
type Accessing p m s a = p a (Const m a) -> s -> Const m s Source
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 a Source
ito :: (s -> (i, a)) -> IndexedGetter i s a Source
Combinators for Getters and Folds
(^.) :: s -> Getting a s a -> a infixl 8 Source
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 a Source
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) => Optical p (->) (Const r) s s a a -> p a r -> m r Source
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 a Source
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) => Optical p (->) (Const r) s s a a -> p a r -> m r Source
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) infixl 8 Source
View the index and value of an IndexedGetter
or IndexedLens
.
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 (.
).
(^@.
) :: 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 r Source
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 r Source
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.
coerce :: (Contravariant f, Functor f) => f a -> f b Source
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
newtype Const a b :: * -> * -> *
Bitraversable Const | |
Bifunctor Const | |
Bifoldable Const | |
Effective Identity r (Const r) | |
Functor (Const m) | |
Monoid m => Applicative (Const m) | |
Foldable (Const m) | |
Traversable (Const m) | |
Generic1 (Const a) | |
Contravariant (Const a) | |
Semigroup m => Apply (Const m) | |
Generic (Const a b) | |
Monoid a => Monoid (Const a b) | |
Semigroup a => Semigroup (Const a b) | |
Wrapped (Const a x) | |
(~) * t (Const a' x') => Rewrapped (Const a x) t | |
type Rep1 (Const a) = D1 D1Const (C1 C1_0Const (S1 S1_0_0Const (Rec0 a))) | |
type Rep (Const a b) = D1 D1Const (C1 C1_0Const (S1 S1_0_0Const (Rec0 a))) | |
type Unwrapped (Const a x) = a |
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 |