Safe Haskell | Trustworthy |
---|---|
Language | Haskell2010 |
Zipping and aligning of functors with non-uniform shapes.
Synopsis
- class Functor f => Semialign f where
- class Semialign f => Align f where
- nil :: f a
- class Semialign f => Unalign f where
- unalign :: f (These a b) -> (f a, f b)
- unalignWith :: (c -> These a b) -> f c -> (f a, f b)
- class Semialign f => Zip f where
- full :: a -> f a
- class Semialign f => Unzip f where
- unzipDefault :: Functor f => f (a, b) -> (f a, f b)
- malign :: (Semialign f, Monoid a) => f a -> f a -> f a
- salign :: (Semialign f, Semigroup a) => f a -> f a -> f a
- padZip :: Semialign f => f a -> f b -> f (Maybe a, Maybe b)
- padZipWith :: Semialign 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
Documentation
class Functor f => Semialign f where Source #
Functors supporting a zip
and align
operations that takes the
intersection and union of non-uniform shapes.
Minimal definition: either align
or alignWith
and either zip
or zipWith
.
Laws
The laws of align
and zip
resemble lattice laws.
There is a plenty of laws, but they are simply satisfied.
And an addition property if f
is Foldable
,
which tries to enforce align
-feel:
neither values are duplicated nor lost.
Note: join
f x = f x x
Idempotency
join align ≡ fmap (join These) join zip ≡ fmap (join (,))
Commutativity
align x y ≡ swap <$> align y x zip x y ≡ swap <$> zip y x
Associativity
align x (align y z) ≡ assoc <$> align (align x y) z zip x (zip y z) ≡ assoc <$> zip (zip x y) z
Absorption
fst <$> zip xs (align xs ys) ≡ xs toThis <$> align xs (zip xs ys) ≡ This <$> xs where toThis (This a) = This a toThis (These a _) = This a toThis (That b) = That b
With
alignWith f a b ≡ f <$> align a b zipWith f a b ≡ f <$> zip a b
Functoriality
align (f <$> x) (g <$> y) ≡ bimap f g <$> align x y zip (f <$> x) (g <$> y) ≡ bimap f g <$> zip x y
Zippyness
fmap fst (zip x x) ≡ x fmap snd (zip x x) ≡ x zip (fmap fst x) (fmap snd x) ≡ x
Alignedness, if f
is Foldable
toList x ≡ toListOf (folded . here) (align x y) ≡ mapMaybe justHere (toList (align x y))
Distributivity
align (zip xs ys) zs ≡ undistrThesePair <$> zip (align xs zs) (align ys zs) distrPairThese <$> zip (align xs ys) zs ≡ align (zip xs zs) (zip ys zs) zip (align xs ys) zs ≡ undistrPairThese <$> align (zip xs zs) (zip ys zs)
Note, the following doesn't hold:
distrThesePair <$> align (zip xs ys) zs ≢ zip (align xs zs) (align ys zs)
when xs = []
and ys = zs = [0]
, then
the left hand side is "only" [(
,
but the right hand side is That
0, That
0)][(
.That
0, These
0 0)]
align :: f a -> f b -> f (These a b) Source #
Analogous to
, combines two structures by taking the union of
their shapes and using zip
to hold the elements.These
alignWith :: (These a b -> c) -> f a -> f b -> f c Source #
Analogous to
, combines two structures by taking the union of
their shapes and combining the elements with the given function.zipWith
zip :: f a -> f b -> f (a, b) Source #
Combines to structures by taking the intersection of their shapes and using pair to hold the elements.
zipWith :: (a -> b -> c) -> f a -> f b -> f c Source #
Combines to structures by taking the intersection of their shapes and combining the elements with the given function.
Instances
class Semialign f => Align f where Source #
Instances
Align [] Source # | |
Defined in Data.Semialign.Internal | |
Align Maybe Source # | |
Defined in Data.Semialign.Internal | |
Align ZipList Source # | |
Defined in Data.Semialign.Internal | |
Align IntMap Source # | |
Defined in Data.Semialign.Internal | |
Align Seq Source # | |
Defined in Data.Semialign.Internal | |
Align Vector Source # | |
Defined in Data.Semialign.Internal | |
(Eq k, Hashable k) => Align (HashMap k) Source # | |
Defined in Data.Semialign.Internal | |
Ord k => Align (Map k) Source # | |
Defined in Data.Semialign.Internal | |
Align (Proxy :: Type -> Type) Source # | |
Defined in Data.Semialign.Internal | |
Monad m => Align (Stream m) Source # | |
Defined in Data.Semialign.Internal | |
Monad m => Align (Bundle m v) Source # | |
Defined in Data.Semialign.Internal | |
(Align f, Align g) => Align (Product f g) Source # | |
Defined in Data.Semialign.Internal | |
(Align f, Semialign g) => Align (Compose f g) Source # | |
Defined in Data.Semialign.Internal |
class Semialign f => Unalign f where Source #
Alignable functors supporting an "inverse" to align
: splitting
a union shape into its component parts.
Laws
uncurry align (unalign xs) ≡ xs unalign (align xs ys) ≡ (xs, ys)
Compatibility note
In version 1 unalign
was changed to return (f a, f b)
pair,
instead of (f (Just a), f (Just b))
. Old behaviour can be achieved with
if ever needed.
>>>
unzipWith (unalign . Just) [This 'a', That 'b', These 'c' 'd']
([Just 'a',Nothing,Just 'c'],[Nothing,Just 'b',Just 'd'])
unalign :: f (These a b) -> (f a, f b) Source #
unalignWith :: (c -> These a b) -> f c -> (f a, f b) Source #
class Semialign f => Zip f where Source #
A unit of zip
.
fst <$> zip xs (full y) ≡ xs snd <$> zip (full x) ys ≡ ys
Instances
Zip [] Source # | |
Defined in Data.Semialign.Internal | |
Zip Maybe Source # | |
Defined in Data.Semialign.Internal | |
Zip ZipList Source # | |
Defined in Data.Semialign.Internal | |
Zip Identity Source # | |
Defined in Data.Semialign.Internal | |
Zip NonEmpty Source # | |
Defined in Data.Semialign.Internal | |
Zip Tree Source # | |
Defined in Data.Semialign.Internal | |
Zip (Proxy :: Type -> Type) Source # | |
Defined in Data.Semialign.Internal | |
Zip (Tagged b) Source # | |
Defined in Data.Semialign.Internal | |
Zip ((->) e :: Type -> Type) Source # | |
Defined in Data.Semialign.Internal | |
(Zip f, Zip g) => Zip (Product f g) Source # | |
Defined in Data.Semialign.Internal | |
(Zip f, Zip g) => Zip (Compose f g) Source # | |
Defined in Data.Semialign.Internal |
class Semialign f => Unzip f where Source #
Right inverse of zip
.
This class is definable for every Functor
. See unzipDefault
.
Laws
uncurry zip (unzip xs) ≡ xs unzip (zip xs xs) ≡ (xs, xs)
Note:
unzip (zip xs ys) ≢ (xs, _) or (_, ys)
For sequence-like types this holds, but for Map-like it doesn't.
Instances
Unzip [] Source # | |
Unzip Maybe Source # | |
Unzip ZipList Source # | |
Unzip Identity Source # | |
Unzip NonEmpty Source # | |
Unzip IntMap Source # | |
Unzip Tree Source # | |
Unzip Seq Source # | |
Unzip Vector Source # | |
(Eq k, Hashable k) => Unzip (HashMap k) Source # | |
Ord k => Unzip (Map k) Source # | |
Unzip (Proxy :: Type -> Type) Source # | |
Unzip (Tagged b) Source # | |
(Unzip f, Unzip g) => Unzip (Product f g) Source # | |
(Unzip f, Unzip g) => Unzip (Compose f g) Source # | |
unzipDefault :: Functor f => f (a, b) -> (f a, f b) Source #
Specialized aligns
salign :: (Semialign f, Semigroup a) => f a -> f a -> f a Source #
Align two structures and combine with <>
.
lpadZipWith :: (Maybe a -> b -> c) -> [a] -> [b] -> [c] Source #
Left-padded zipWith
.
rpadZipWith :: (a -> Maybe b -> c) -> [a] -> [b] -> [c] Source #
Right-padded zipWith
.