Safe Haskell | Safe |
---|---|
Language | Haskell2010 |
A tiny library for composing indexed 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 lens
library.
This library tries to provide something similar for indexed traversals.
Many data structures provide functions which map or traverse while providing
access to an index. For example, containers
provides mapWithKey
and
traverseWithKey
functions for Map
. Using this module, it is possible
to compose such maps and traversals, while combining indices using some
Monoid
.
To use this library, first import Control.Category
, since you will need
the more general version of composition defined in that module.
Next, wrap any maps or traversals you wish to use with the WithIndex
constructor. You may also need to change the index type using the reindex
function. These wrapped functions can be composed using the (Category
)
composition operator.
Regular maps and traversals can also be used, via the withoutIndex
function.
Documentation
newtype WithIndex i a b Source #
A wrapper for a mapping or traversal function which uses an index.
For example, using the containers
library:
WithIndex mapWithKey :: WithIndex i (a -> b) (Map i a -> Map i b) WithIndex foldMapWithKey :: Monoid m => WithIndex i (a -> m) (Map i a -> m) WithIndex traverseWithKey :: Applicative t => WithIndex i (a -> t b) (Map i a -> t (Map i b))
These wrapped functions can be composed using the (Category
) 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 $ WithIndex mapWithKey . WithIndex mapWithKey :: Monoid i => (i -> a -> b) -> Map i (Map i a) -> Map i (Map i b)
reindex :: (i -> j) -> WithIndex i a b -> WithIndex j a b Source #
Change the Monoid
used to combine indices.
For example, to keep track of only the first index seen, use Data.Monoid.First
:
reindex (First . pure) :: WithIndex i a b -> WithIndex (First i) a b
or keep track of all indices using a list
reindex (: []) :: WithIndex i a b -> WithIndex [i] a b
withoutIndex :: Monoid i => (a -> b) -> WithIndex i a b Source #
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 Data.Map.map :: Monoid i => WithIndex i (a -> b) (Map i (Map k a) -> Map i (Map k b))