with-index-0.1.0.0: A tiny library for composing indexed traversals

Safe HaskellSafe
LanguageHaskell2010

Data.WithIndex

Description

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.

Synopsis

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)

Constructors

WithIndex 

Fields

Instances

Monoid i => Category * (WithIndex i) Source # 

Methods

id :: cat a a #

(.) :: cat b c -> cat a b -> cat a c #

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