these-0.7.3: An either-or-both data type & a generalized 'zip with padding' typeclass

Safe Haskell | None
Language | Haskell98

Data.Align

Contents

- Specialized aligns
- Unalign
- Crosswalk
- Bicrosswalk

Description

`These`-based zipping and unzipping of functors with non-uniform shapes, plus traversal of (bi)foldable (bi)functors through said functors.

Synopsis

- class Functor f => Align f where
- malign :: (Align f, Monoid a) => f a -> f a -> f a
- salign :: (Align f, Semigroup a) => f a -> f a -> f a
- padZip :: Align f => f a -> f b -> f (Maybe a, Maybe b)
- padZipWith :: Align f => (Maybe a -> Maybe b -> c) -> f a -> f b -> f c
- lpadZip :: [a] -> [b] -> [(Maybe a, b)]
- lpadZipWith :: (Maybe a -> b -> c) -> [a] -> [b] -> [c]
- rpadZip :: [a] -> [b] -> [(a, Maybe b)]
- rpadZipWith :: (a -> Maybe b -> c) -> [a] -> [b] -> [c]
- alignVectorWith :: (Vector v a, Vector v b, Vector v c) => (These a b -> c) -> v a -> v b -> v c
- class Align f => Unalign f where
- class (Functor t, Foldable t) => Crosswalk t where
- class (Bifunctor t, Bifoldable t) => Bicrosswalk t where

# Documentation

class Functor f => Align f where Source #

Functors supporting a zip operation that takes the union of non-uniform shapes.

If your functor is actually a functor from `Kleisli Maybe` to `Hask` (so it supports `maybeMap :: (a -> Maybe b) -> f a -> f b`), then an `Align` instance is making your functor lax monoidal w.r.t. the cartesian monoidal structure on `Kleisli Maybe`, because `These` is the cartesian product in that category `(a -> Maybe (These b c) ~ (a -> Maybe b, a -> Maybe c))`. This insight is due to rwbarton.

Minimal definition: `nil` and either `align` or `alignWith`.

Laws:

    (`align` nil) = fmap This
    (nil `align`) = fmap That
    join align = fmap (join These)
    align (f <$> x) (g <$> y) = bimap f g <$> align x y
    alignWith f a b = f <$> align a b

Minimal complete definition

nil, (align | alignWith)

Methods

nil :: f a Source #

An empty strucutre. ``align``ing with ``nil`` will produce a structure with the same shape and elements as the other input, modulo ``This`` or ``That``.

align :: f a -> f b -> f (These a b) Source #

Analogous to ``zip``, combines two structures by taking the union of their shapes and using ``These`` to hold the elements.

alignWith :: (These a b -> c) -> f a -> f b -> f c Source #

Analogous to ``zipWith``, combines two structures by taking the union of their shapes and combining the elements with the given function.

Instances

Align [] Source # |
Methods nil :: [a] Source # align :: [a] -> [b] -> [These a b] Source # alignWith :: (These a b -> c) -> [a] -> [b] -> [c] Source #
Align Maybe Source # |
Methods nil :: Maybe a Source # align :: Maybe a -> Maybe b -> Maybe (These a b) Source # alignWith :: (These a b -> c) -> Maybe a -> Maybe b -> Maybe c Source #
Align ZipList Source # |
Methods nil :: ZipList a Source # align :: ZipList a -> ZipList b -> ZipList (These a b) Source # alignWith :: (These a b -> c) -> ZipList a -> ZipList b -> ZipList c Source #
Align IntMap Source # |
Methods nil :: IntMap a Source # align :: IntMap a -> IntMap b -> IntMap (These a b) Source # alignWith :: (These a b -> c) -> IntMap a -> IntMap b -> IntMap c Source #
Align Seq Source # |
Methods nil :: Seq a Source # align :: Seq a -> Seq b -> Seq (These a b) Source # alignWith :: (These a b -> c) -> Seq a -> Seq b -> Seq c Source #
Align Vector Source # |
Methods nil :: Vector a Source # align :: Vector a -> Vector b -> Vector (These a b) Source # alignWith :: (These a b -> c) -> Vector a -> Vector b -> Vector c Source #
(Eq k, Hashable k) => Align (HashMap k) Source # |
Methods nil :: HashMap k a Source # align :: HashMap k a -> HashMap k b -> HashMap k (These a b) Source # alignWith :: (These a b -> c) -> HashMap k a -> HashMap k b -> HashMap k c Source #
Ord k => Align (Map k) Source # |
Methods nil :: Map k a Source # align :: Map k a -> Map k b -> Map k (These a b) Source # alignWith :: (These a b -> c) -> Map k a -> Map k b -> Map k c Source #
Monad m => Align (Stream m) Source # |
Methods nil :: Stream m a Source # align :: Stream m a -> Stream m b -> Stream m (These a b) Source # alignWith :: (These a b -> c) -> Stream m a -> Stream m b -> Stream m c Source #
Monad m => Align (Bundle m v) Source # |
Methods nil :: Bundle m v a Source # align :: Bundle m v a -> Bundle m v b -> Bundle m v (These a b) Source # alignWith :: (These a b -> c) -> Bundle m v a -> Bundle m v b -> Bundle m v c Source #
(Align f, Align g) => Align (Product * f g) Source # |
Methods nil :: Product * f g a Source # align :: Product * f g a -> Product * f g b -> Product * f g (These a b) Source # alignWith :: (These a b -> c) -> Product * f g a -> Product * f g b -> Product * f g c Source #

# Specialized aligns

malign :: (Align f, Monoid a) => f a -> f a -> f a Source #

Align two structures and combine with `mappend`.

See `salign`. `malign` will be deprecated after `Semigroup` becomes a super class of `Monoid`

salign :: (Align f, Semigroup a) => f a -> f a -> f a Source #

Align two structures and combine with `<>`.

padZip :: Align f => f a -> f b -> f (Maybe a, Maybe b) Source #

Align two structures as in `zip`, but filling in blanks with `Nothing`.

padZipWith :: Align f => (Maybe a -> Maybe b -> c) -> f a -> f b -> f c Source #

Align two structures as in `zipWith`, but filling in blanks with `Nothing`.

lpadZip :: [a] -> [b] -> [(Maybe a, b)] Source #

Left-padded `zip`.

lpadZipWith :: (Maybe a -> b -> c) -> [a] -> [b] -> [c] Source #

Left-padded `zipWith`.

rpadZip :: [a] -> [b] -> [(a, Maybe b)] Source #

Right-padded `zip`.

rpadZipWith :: (a -> Maybe b -> c) -> [a] -> [b] -> [c] Source #

Right-padded `zipWith`.

alignVectorWith :: (Vector v a, Vector v b, Vector v c) => (These a b -> c) -> v a -> v b -> v c Source #

# Unalign

class Align f => Unalign f where Source #

Alignable functors supporting an "inverse" to `align`: splitting a union shape into its component parts.

Minimal definition: nothing; a default definition is provided, but it may not have the desired definition for all functors. See the source for more information.

Laws:

    unalign nil                 = (nil,           nil)
    unalign (This        <$> x) = (Just    <$> x, Nothing <$  x)
    unalign (That        <$> y) = (Nothing <$  y, Just    <$> y)
    unalign (join These  <$> x) = (Just    <$> x, Just    <$> x)
    unalign ((x `These`) <$> y) = (Just x  <$  y, Just    <$> y)
    unalign ((`These` y) <$> x) = (Just    <$> x, Just y  <$  x)

Methods

unalign :: f (These a b) -> (f (Maybe a), f (Maybe b)) Source #

Instances

Unalign [] Source # |
Methods unalign :: [These a b] -> ([Maybe a], [Maybe b]) Source #
Unalign Maybe Source # |
Methods unalign :: Maybe (These a b) -> (Maybe (Maybe a), Maybe (Maybe b)) Source #
Unalign ZipList Source # |
Methods unalign :: ZipList (These a b) -> (ZipList (Maybe a), ZipList (Maybe b)) Source #
Monad m => Unalign (Stream m) Source # |
Methods unalign :: Stream m (These a b) -> (Stream m (Maybe a), Stream m (Maybe b)) Source #
(Unalign f, Unalign g) => Unalign (Product * f g) Source # |
Methods unalign :: Product * f g (These a b) -> (Product * f g (Maybe a), Product * f g (Maybe b)) Source #

# Crosswalk

class (Functor t, Foldable t) => Crosswalk t where Source #

Foldable functors supporting traversal through an alignable functor.

Minimal definition: `crosswalk` or `sequenceL`.

Laws:

    crosswalk (const nil) = const nil
    crosswalk f = sequenceL . fmap f

Minimal complete definition

crosswalk | sequenceL

Methods

crosswalk :: Align f => (a -> f b) -> t a -> f (t b) Source #

sequenceL :: Align f => t (f a) -> f (t a) Source #

Instances

Crosswalk [] Source # |
Methods crosswalk :: Align f => (a -> f b) -> [a] -> f [b] Source # sequenceL :: Align f => [f a] -> f [a] Source #
Crosswalk Maybe Source # |
Methods crosswalk :: Align f => (a -> f b) -> Maybe a -> f (Maybe b) Source # sequenceL :: Align f => Maybe (f a) -> f (Maybe a) Source #
Crosswalk Identity Source # |
Methods crosswalk :: Align f => (a -> f b) -> Identity a -> f (Identity b) Source # sequenceL :: Align f => Identity (f a) -> f (Identity a) Source #
Crosswalk Seq Source # |
Methods crosswalk :: Align f => (a -> f b) -> Seq a -> f (Seq b) Source # sequenceL :: Align f => Seq (f a) -> f (Seq a) Source #
Crosswalk Vector Source # |
Methods crosswalk :: Align f => (a -> f b) -> Vector a -> f (Vector b) Source # sequenceL :: Align f => Vector (f a) -> f (Vector a) Source #
Crosswalk (These a) Source # |
Methods crosswalk :: Align f => (a -> f b) -> These a a -> f (These a b) Source # sequenceL :: Align f => These a (f a) -> f (These a a) Source #

# Bicrosswalk

class (Bifunctor t, Bifoldable t) => Bicrosswalk t where Source #

Bifoldable bifunctors supporting traversal through an alignable functor.

Minimal definition: `bicrosswalk` or `bisequenceL`.

Laws:

    bicrosswalk (const empty) (const empty) = const empty
    bicrosswalk f g = bisequenceL . bimap f g

Minimal complete definition

bicrosswalk | bisequenceL

Methods

bicrosswalk :: Align f => (a -> f c) -> (b -> f d) -> t a b -> f (t c d) Source #

bisequenceL :: Align f => t (f a) (f b) -> f (t a b) Source #

Instances

Bicrosswalk Either Source # |
Methods bicrosswalk :: Align f => (a -> f c) -> (b -> f d) -> Either a b -> f (Either c d) Source # bisequenceL :: Align f => Either (f a) (f b) -> f (Either a b) Source #
Bicrosswalk These Source # |
Methods bicrosswalk :: Align f => (a -> f c) -> (b -> f d) -> These a b -> f (These c d) Source # bisequenceL :: Align f => These (f a) (f b) -> f (These a b) Source #