Copyright | (C) 2012-2016 Edward Kmett (C) 2006-2012 Neil Mitchell |
---|---|
License | BSD-style (see the file LICENSE) |
Maintainer | Edward Kmett <ekmett@gmail.com> |
Stability | experimental |
Portability | Rank2Types |
Safe Haskell | Trustworthy |
Language | Haskell2010 |
Synopsis
- template :: forall s a. ( Data s, Typeable a) => Traversal' s a
- tinplate :: ( Data s, Typeable a) => Traversal' s a
- uniplate :: Data a => Traversal' a a
- biplate :: forall s a. ( Data s, Typeable a) => Traversal' s a
- upon :: forall p f s a. ( Indexable [ Int ] p, Applicative f, Data s, Data a) => (s -> a) -> p a (f a) -> s -> f s
- upon' :: forall s a. ( Data s, Data a) => (s -> a) -> IndexedLens' [ Int ] s a
- onceUpon :: forall s a. ( Data s, Typeable a) => (s -> a) -> IndexedTraversal' Int s a
- onceUpon' :: forall s a. ( Data s, Typeable a) => (s -> a) -> IndexedLens' Int s a
- gtraverse :: ( Applicative f, Data a) => ( forall d. Data d => d -> f d) -> a -> f a
Generic Traversal
uniplate :: Data a => Traversal' a a Source #
Field Accessor Traversal
upon :: forall p f s a. ( Indexable [ Int ] p, Applicative f, Data s, Data a) => (s -> a) -> p a (f a) -> s -> f s Source #
This automatically constructs a
Traversal'
from an function.
>>>
(2,4) & upon fst *~ 5
(10,4)
There are however, caveats on how this function can be used!
First, the user supplied function must access only one field of the specified type. That is to say the target
must be a single element that would be visited by
holesOnOf
template
uniplate
Note: this even permits a number of functions to be used directly.
>>>
[1,2,3,4] & upon head .~ 0
[0,2,3,4]
>>>
[1,2,3,4] & upon last .~ 5
[1,2,3,5]
>>>
[1,2,3,4] ^? upon tail
Just [2,3,4]
>>>
"" ^? upon tail
Nothing
Accessing parents on the way down to children is okay:
>>>
[1,2,3,4] & upon (tail.tail) .~ [10,20]
[1,2,10,20]
Second, the structure must not contain strict or unboxed fields of the same type that will be visited by
Data
upon
:: (Data
s,Data
a) => (s -> a) ->IndexedTraversal'
[Int] s a
upon' :: forall s a. ( Data s, Data a) => (s -> a) -> IndexedLens' [ Int ] s a Source #
The design of
onceUpon'
doesn't allow it to search inside of values of type
a
for other values of type
a
.
upon'
provides this additional recursion.
Like
onceUpon'
,
upon'
trusts the user supplied function more than
upon
using it directly
as the accessor. This enables reading from the resulting
Lens
to be considerably faster at the risk of
generating an illegal lens.
>>>
upon' (tail.tail) .~ [10,20] $ [1,2,3,4]
[1,2,10,20]
onceUpon :: forall s a. ( Data s, Typeable a) => (s -> a) -> IndexedTraversal' Int s a Source #
This automatically constructs a
Traversal'
from a field accessor.
The index of the
Traversal
can be used as an offset into
or into the list
returned by
elementOf
(
indexing
template
)
.
holesOf
template
The design of
onceUpon
doesn't allow it to search inside of values of type
a
for other values of type
a
.
upon
provides this additional recursion, but at the expense of performance.
>>>
onceUpon (tail.tail) .~ [10,20] $ [1,2,3,4] -- BAD
[1,10,20]
>>>
upon (tail.tail) .~ [10,20] $ [1,2,3,4] -- GOOD
[1,2,10,20]
When in doubt, use
upon
instead.
onceUpon' :: forall s a. ( Data s, Typeable a) => (s -> a) -> IndexedLens' Int s a Source #
This more trusting version of
upon
uses your function directly as the getter for a
Lens
.
This means that reading from
upon'
is considerably faster than
upon
.
However, you pay for faster access in two ways:
-
When passed an illegal field accessor,
upon'
will give you aLens
that quietly violates the laws, unlikeupon
, which will give you a legalTraversal
that avoids modifying the target. - Modifying with the lens is slightly slower, since it has to go back and calculate the index after the fact.
When given a legal field accessor, the index of the
Lens
can be used as an offset into
or into the list returned by
elementOf
(
indexed
template
)
.
holesOf
template
When in doubt, use
upon'
instead.