lens-3.1: Lenses, Folds and Traversals

Portability Rank2Types provisional Edward Kmett Trustworthy

Control.Lens.Getter

Description

A Getter s a is just any function (s -> a), which we've flipped into continuation passing style, (a -> r) -> s -> r and decorated with Accessor to obtain:

type Getting 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:

type Getter 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.

type Getter 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.

Synopsis

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 lens-like 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 (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

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 Getting r s t a b, then when r is a Monoid, then you can pass a Fold (or Traversal), otherwise you can only pass this a Getter or Lens.

Building Getters

to :: (s -> a) -> Getter s aSource

Build a Getter from an arbitrary Haskell function.

to f . to g = to (g . f)
a ^. to f = f a
>>> ("hello","world")^.to snd
"world"
>>> 5^.to succ
6
>>> (0, -5)^._2.to abs
5

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 (.)

>>> ("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
>>> _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 (\$).

>>> "hello" % length % succ
6

(^%) :: a -> (a -> b) -> bSource

A version of (%) with much tighter precedence that can be interleaved with (^.)

>>> "hello"^%length
5
>>> import Data.List.Lens
'o'

view :: 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.

view . to = id
>>> view _2 (1,"hello")
"hello"
>>> view (to succ) 5
6
>>> view (_2._1) ("hello",("world","!!!"))
"world"

It may be useful to think of view as having one of these more restrictive signatures:

view ::             Getter s a             -> s -> a
view :: Monoid m => Fold s m               -> s -> m
view ::             Simple Iso s a         -> s -> a
view ::             Simple Lens s a        -> s -> a
view :: Monoid m => Simple Traversal s m   -> s -> m

views :: Getting m s t a b -> (a -> m) -> s -> mSource

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 _2 length (1,"hello")
5
views ::             Getter s a             -> (a -> b) -> s -> b
views :: Monoid m => Fold s a               -> (a -> m) -> s -> m
views ::             Simple Iso s a         -> (a -> b) -> s -> b
views ::             Simple Lens s a        -> (a -> b) -> s -> b
views :: Monoid m => Simple Traversal s a   -> (a -> m) -> s -> m

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.

use :: MonadState s m             => Getter s a             -> m a
use :: (MonadState s m, Monoid r) => Fold s r               -> m r
use :: MonadState s m             => Simple Iso s a         -> m a
use :: MonadState s m             => Simple Lens s a        -> m a
use :: (MonadState s m, Monoid r) => Simple Traversal s r   -> m r

uses :: MonadState s m => Getting e s t a b -> (a -> e) -> m eSource

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.

uses :: MonadState s m             => Getter s a           -> (a -> e) -> m e
uses :: (MonadState s m, Monoid r) => Fold s a             -> (a -> r) -> m r
uses :: MonadState s m             => Simple Lens s a      -> (a -> e) -> m e
uses :: MonadState s m             => Simple Iso s a       -> (a -> e) -> m e
uses :: (MonadState s m, Monoid r) => Simple Traversal s a -> (a -> r) -> m r

query :: MonadReader s m => Getting a s t a b -> m aSource

Query 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.

query :: MonadReader s m             => Getter s a           -> m a
query :: (MonadReader s m, Monoid a) => Fold s a             -> m a
query :: MonadReader s m             => Simple Iso s a       -> m a
query :: MonadReader s m             => Simple Lens s a      -> m a
query :: (MonadReader s m, Monoid a) => Simple Traversal s a -> m a

queries :: MonadReader 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.

queries :: MonadReader s m             => Getter s a           -> (a -> r) -> m r
queries :: (MonadReader s m, Monoid a) => Fold s a             -> (a -> r) -> m r
queries :: MonadReader s m             => Simple Iso s a       -> (a -> r) -> m r
queries :: MonadReader s m             => Simple Lens s a      -> (a -> r) -> m r
queries :: (MonadReader s m, Monoid a) => Simple Traversal s a -> (a -> r) -> m r

Storing Getters

newtype ReifiedGetter s a Source

Useful for storing getters in containers.

Constructors

 ReifyGetter FieldsreflectGetter :: Getter s a

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

Instances

 Functor (Const r) => Gettable (Const r) (Functor (Backwards f), Gettable f) => Gettable (Backwards f) Functor (Accessor r) => Gettable (Accessor r) (Functor (ElementOf f), Gettable f) => Gettable (ElementOf f) This instance is a lie, but it is a useful lie. (Functor (Indexing f), Gettable f) => Gettable (Indexing f) (Functor (Compose f g), Functor f, Gettable g) => Gettable (Compose f g) Functor (Effect m r) => Gettable (Effect m r) Functor (EffectRWS w st m s) => Gettable (EffectRWS w st m s)

data Accessor r a Source

Used instead of Const to report

No instance of (Settable Accessor)

when the user attempts to misuse a Setter as a Getter, rather than a monolithic unification error.

Instances

 (Monad Identity, Gettable (Accessor r)) => Effective Identity r (Accessor r) Functor (Accessor r) (Functor (Accessor r), Monoid r) => Applicative (Accessor r) Functor (Accessor r) => Gettable (Accessor r) (MonadReader b ((->) b), MonadReader a ((->) a)) => Magnify ((->) b) ((->) a) Accessor b a magnify = views