A tiny library for composing WithIndex maps, folds and traversals.
One of the benefits of lenses and traversals is that they can be
created, composed and used, using only the machinery available in base.
For more advanced use cases, there is the
This library tries to provide something similar for WithIndex traversals.
Many data structures provide functions which map or traverse while providing
access to an index. See for example the
TraversableWithIndex type class.
Using this module, it is possible to compose such maps and traversals,
while combining indices using some
To use this library, wrap any maps or traversals you wish to use with the
constructor. You may also need to change the index type using the
function. These wrapped functions can be composed using the composition operator.
Regular maps and traversals can also be used with the
withoutIndex function or
by using the
newtype WithIndex i a b
A wrapper for a mapping or traversal function which uses an index.
For example, using the
WithIndex mapWithKey :: WithIndex i (a -> b) (Map i a -> Map i b)
These wrapped functions can be composed using the composition operator:
WithIndex mapWithKey . WithIndex mapWithKey :: Monoid i => WithIndex i (a -> b) (Map i (Map i a) -> Map i (Map i b))
and then applied using
withIndex $ WithIndex mapWithKey . WithIndex mapWithKey :: Monoid i => (i -> a -> b) -> Map i (Map i a) -> Map i (Map i b)
WithIndex ((i -> a) -> b)
Monoid used to combine indices.
For example, to keep track of only the first index seen, use
reindex (First . pure) :: WithIndex i a b -> WithIndex (First i) a b
or keep track of all indices using a list
reindex singleton :: WithIndex i a b -> WithIndex (List i) a b
withoutIndex :: forall b a i. Monoid i => (a -> b) -> WithIndex i a b
Turn a regular function into an wrapped function, so that it can be composed with other wrapped functions.
For example, to traverse two layers, keeping only the first index:
WithIndex mapWithKey . withoutIndex map :: Monoid i => WithIndex i (a -> b) (Map i (Map k a) -> Map i (Map k b))
applyWithIndex :: forall c a b j i. WithIndex (i -> j) b c -> WithIndex i a b -> WithIndex j a c
Compose two wrapped functions, composing their index types using function application.
This is useful in some circumstances when building up a traversal in an applicative style.
See the test suite for an example.