Copyright | (C) 2011-2015 Edward Kmett |
---|---|

License | BSD-style (see the file LICENSE) |

Maintainer | Edward Kmett <ekmett@gmail.com> |

Stability | provisional |

Portability | portable |

Safe Haskell | Trustworthy |

Language | Haskell98 |

- class (Bifunctor t, Bifoldable t) => Bitraversable t where
- bisequenceA :: (Bitraversable t, Applicative f) => t (f a) (f b) -> f (t a b)
- bisequence :: (Bitraversable t, Monad m) => t (m a) (m b) -> m (t a b)
- bimapM :: (Bitraversable t, Monad m) => (a -> m c) -> (b -> m d) -> t a b -> m (t c d)
- bifor :: (Bitraversable t, Applicative f) => t a b -> (a -> f c) -> (b -> f d) -> f (t c d)
- biforM :: (Bitraversable t, Monad m) => t a b -> (a -> m c) -> (b -> m d) -> m (t c d)
- bimapAccumL :: Bitraversable t => (a -> b -> (a, c)) -> (a -> d -> (a, e)) -> a -> t b d -> (a, t c e)
- bimapAccumR :: Bitraversable t => (a -> b -> (a, c)) -> (a -> d -> (a, e)) -> a -> t b d -> (a, t c e)
- bimapDefault :: forall t a b c d. Bitraversable t => (a -> b) -> (c -> d) -> t a c -> t b d
- bifoldMapDefault :: forall t m a b. (Bitraversable t, Monoid m) => (a -> m) -> (b -> m) -> t a b -> m

# Documentation

class (Bifunctor t, Bifoldable t) => Bitraversable t where #

`Bitraversable`

identifies bifunctorial data structures whose elements can
be traversed in order, performing `Applicative`

or `Monad`

actions at each
element, and collecting a result structure with the same shape.

As opposed to `Traversable`

data structures, which have one variety of
element on which an action can be performed, `Bitraversable`

data structures
have two such varieties of elements.

A definition of `bitraverse`

must satisfy the following laws:

*naturality*

for every applicative transformation`bitraverse`

(t . f) (t . g) ≡ t .`bitraverse`

f g`t`

*identity*`bitraverse`

`Identity`

`Identity`

≡`Identity`

*composition*`Compose`

.`fmap`

(`bitraverse`

g1 g2) .`bitraverse`

f1 f2 ≡`traverse`

(`Compose`

.`fmap`

g1 . f1) (`Compose`

.`fmap`

g2 . f2)

where an *applicative transformation* is a function

t :: (`Applicative`

f,`Applicative`

g) => f a -> g a

preserving the `Applicative`

operations:

t (`pure`

x) =`pure`

x t (f`<*>`

x) = t f`<*>`

t x

and the identity functor `Identity`

and composition functors `Compose`

are
defined as

newtype Identity a = Identity { runIdentity :: a } instance Functor Identity where fmap f (Identity x) = Identity (f x) instance Applicative Identity where pure = Identity Identity f <*> Identity x = Identity (f x) newtype Compose f g a = Compose (f (g a)) instance (Functor f, Functor g) => Functor (Compose f g) where fmap f (Compose x) = Compose (fmap (fmap f) x) instance (Applicative f, Applicative g) => Applicative (Compose f g) where pure = Compose . pure . pure Compose f <*> Compose x = Compose ((<*>) <$> f <*> x)

Some simple examples are `Either`

and '(,)':

instance Bitraversable Either where bitraverse f _ (Left x) = Left <$> f x bitraverse _ g (Right y) = Right <$> g y instance Bitraversable (,) where bitraverse f g (x, y) = (,) <$> f x <*> g y

`Bitraversable`

relates to its superclasses in the following ways:

`bimap`

f g ≡`runIdentity`

.`bitraverse`

(`Identity`

. f) (`Identity`

. g)`bifoldMap`

f g =`getConst`

.`bitraverse`

(`Const`

. f) (`Const`

. g)

These are available as `bimapDefault`

and `bifoldMapDefault`

respectively.

bitraverse :: Applicative f => (a -> f c) -> (b -> f d) -> t a b -> f (t c d) #

Evaluates the relevant functions at each element in the structure, running the action, and builds a new structure with the same shape, using the elements produced from sequencing the actions.

`bitraverse`

f g ≡`bisequenceA`

.`bimap`

f g

For a version that ignores the results, see `bitraverse_`

.

Bitraversable Either # | |

Bitraversable (,) # | |

Bitraversable Arg # | |

Bitraversable (K1 i) # | |

Bitraversable ((,,) x) # | |

Bitraversable (Const *) # | |

Bitraversable (Tagged *) # | |

Bitraversable (Constant *) # | |

Bitraversable ((,,,) x y) # | |

Bitraversable ((,,,,) x y z) # | |

Traversable f => Bitraversable (Clown * * f) # | |

Bitraversable p => Bitraversable (Flip * * p) # | |

Traversable g => Bitraversable (Joker * * g) # | |

Bitraversable p => Bitraversable (WrappedBifunctor * * p) # | |

Bitraversable ((,,,,,) x y z w) # | |

(Bitraversable p, Bitraversable q) => Bitraversable (Sum * * p q) # | |

(Bitraversable f, Bitraversable g) => Bitraversable (Product * * f g) # | |

Bitraversable ((,,,,,,) x y z w v) # | |

(Traversable f, Bitraversable p) => Bitraversable (Tannen * * * f p) # | |

(Bitraversable p, Traversable f, Traversable g) => Bitraversable (Biff * * * * p f g) # | |

bisequenceA :: (Bitraversable t, Applicative f) => t (f a) (f b) -> f (t a b) #

Sequences all the actions in a structure, building a new structure with the
same shape using the results of the actions. For a version that ignores the
results, see `bisequenceA_`

.

`bisequenceA`

≡`bitraverse`

`id`

`id`

bisequence :: (Bitraversable t, Monad m) => t (m a) (m b) -> m (t a b) #

As `bisequenceA`

, but uses evidence that `m`

is a `Monad`

rather than an
`Applicative`

. For a version that ignores the results, see `bisequence_`

.

`bisequence`

≡`bimapM`

`id`

`id`

`bisequence`

≡`unwrapMonad`

.`bisequenceA`

.`bimap`

`WrapMonad`

`WrapMonad`

bimapM :: (Bitraversable t, Monad m) => (a -> m c) -> (b -> m d) -> t a b -> m (t c d) #

As `bitraverse`

, but uses evidence that `m`

is a `Monad`

rather than an
`Applicative`

. For a version that ignores the results, see `bimapM_`

.

`bimapM`

f g ≡`bisequence`

.`bimap`

f g`bimapM`

f g ≡`unwrapMonad`

.`bitraverse`

(`WrapMonad`

. f) (`WrapMonad`

. g)

bifor :: (Bitraversable t, Applicative f) => t a b -> (a -> f c) -> (b -> f d) -> f (t c d) #

`bifor`

is `bitraverse`

with the structure as the first argument. For a
version that ignores the results, see `bifor_`

.

biforM :: (Bitraversable t, Monad m) => t a b -> (a -> m c) -> (b -> m d) -> m (t c d) #

bimapAccumL :: Bitraversable t => (a -> b -> (a, c)) -> (a -> d -> (a, e)) -> a -> t b d -> (a, t c e) #

The `bimapAccumL`

function behaves like a combination of `bimap`

and
`bifoldl`

; it traverses a structure from left to right, threading a state
of type `a`

and using the given actions to compute new elements for the
structure.

bimapAccumR :: Bitraversable t => (a -> b -> (a, c)) -> (a -> d -> (a, e)) -> a -> t b d -> (a, t c e) #

The `bimapAccumR`

function behaves like a combination of `bimap`

and
`bifoldl`

; it traverses a structure from right to left, threading a state
of type `a`

and using the given actions to compute new elements for the
structure.

bimapDefault :: forall t a b c d. Bitraversable t => (a -> b) -> (c -> d) -> t a c -> t b d #

A default definition of `bimap`

in terms of the `Bitraversable`

operations.

`bimapDefault`

f g ≡`runIdentity`

.`bitraverse`

(`Identity`

. f) (`Identity`

. g)

bifoldMapDefault :: forall t m a b. (Bitraversable t, Monoid m) => (a -> m) -> (b -> m) -> t a b -> m #

A default definition of `bifoldMap`

in terms of the `Bitraversable`

operations.

`bifoldMapDefault`

f g ≡`getConst`

.`bitraverse`

(`Const`

. f) (`Const`

. g)