semialign 1.1.0.1 → 1.4
raw patch · 6 files changed
Files
- CHANGELOG.md +34/−0
- semialign.cabal +29/−43
- src/Data/Crosswalk.hs +0/−6
- src/Data/Semialign/Indexed.hs +9/−0
- src/Data/Semialign/Internal.hs +211/−70
- src/Data/Zip.hs +0/−2
CHANGELOG.md view
@@ -1,3 +1,37 @@+# 1.4++- Reorder class hierarchy. `Unzip` is now at the bottom, right above `Functor`.+ There are two ways things may break:+ - You may need to add `Unzip` instance if you haven't one already, for example:+ `instance Unzip ((->) e) where unzip = unzipDefault` was added in this patch.+ - `Unzip f` doesn't imply whole hierarchy, so you may need to change `Unzip f` to `Zip f`+ in the constraints of some of your functions.+- Relax laws of Unalign allowing list-like instances.+ - Add `Unalign []` and `Unalign Vector` instances.++# 1.3.1++- Support GHC-8.6.5...GHC-9.10.1++# 1.3++- Depend on `bifunctor-classes-compat` instead of `bifunctors`+ See changelog note in `bifunctors-5.6`: https://hackage.haskell.org/package/bifunctors-5.6/changelog+ This is breaking change, but affects only GHC-8.0 and older users.+ In that case you should check various combinations of newer/older+ `bifunctors`, `these`, and `semialign` packages.++# 1.2.0.1++- GHC-9.2 support++# 1.2++- Migrate `SemialignWithIndex` and `ZipWithIndex` to this package,+ using `FunctorWithIndex` from `indexed-traversable`.+- Add `RepeatWithIndex` type-class.+- Poly-kinded instances (notably `Tagged`)+ # 1.1.0.1 - Drop `base-compat` dependency
semialign.cabal view
@@ -1,10 +1,10 @@ cabal-version: >=1.10 name: semialign-version: 1.1.0.1+version: 1.4 synopsis: Align and Zip type-classes from the common Semialign ancestor. -homepage: https://github.com/isomorphism/these+homepage: https://github.com/haskellari/these license: BSD3 license-file: LICENSE author: C. McCann, Oleg Grenrus@@ -21,21 +21,22 @@ forming lattice-like structure. tested-with:- GHC ==7.4.2- || ==7.6.3- || ==7.8.4- || ==7.10.3- || ==8.0.2- || ==8.2.2- || ==8.4.4- || ==8.6.5- || ==8.8.3- || ==8.10.1- , GHCJS ==8.4+ GHC ==8.6.5+ || ==8.8.4+ || ==8.10.7+ || ==9.0.2+ || ==9.2.8+ || ==9.4.8+ || ==9.6.6+ || ==9.8.4+ || ==9.10.1+ || ==9.12.4+ || ==9.14.1 source-repository head type: git- location: https://github.com/isomorphism/these.git+ location: https://github.com/haskellari/these.git+ subdir: semialign flag semigroupoids description: Build with semigroupoids dependency@@ -44,52 +45,37 @@ library default-language: Haskell2010- ghc-options: -Wall+ ghc-options: -Wall -Wno-trustworthy-safe - if impl(ghc >=8.0)- ghc-options: -Wno-trustworthy-safe+ if impl(ghc >=9.2)+ ghc-options: -Wno-noncanonical-monoid-instances hs-source-dirs: src exposed-modules: Data.Align Data.Crosswalk Data.Semialign+ Data.Semialign.Indexed Data.Zip other-modules: Data.Semialign.Internal -- ghc boot libs build-depends:- base >=4.5.1.0 && <4.15- , containers >=0.4.2.1 && <0.7- , transformers >=0.3.0.0 && <0.6+ base >=4.12.0.0 && <4.23+ , containers >=0.6.0.1 && <0.9 -- These- build-depends: these >=1 && <1.2+ build-depends: these >=1.2.1 && <1.3 -- other dependencies build-depends:- hashable >=1.2.7.0 && <1.4- , tagged >=0.8.6 && <0.9- , unordered-containers >=0.2.8.0 && <0.3- , vector >=0.12.0.2 && <0.13-- -- base shims- if !impl(ghc >=8.2)- build-depends: bifunctors >=5.5.4 && <5.6-- if !impl(ghc >=8.0)- build-depends:- semigroups >=0.18.5 && <0.20- , transformers >=0.3.0.0 && <0.6- , transformers-compat >=0.6.5 && <0.7-- -- Ensure Data.Functor.Classes is always available- if impl(ghc >=7.10)- build-depends: transformers >=0.4.2.0-- if impl(ghc <7.5)- build-depends: ghc-prim+ hashable >=1.4.4.0 && <1.6+ , indexed-traversable >=0.1.4 && <0.2+ , indexed-traversable-instances >=0.1.2 && <0.2+ , tagged >=0.8.8 && <0.9+ , unordered-containers >=0.2.8.0 && <0.3+ , vector >=0.13.0.0 && <0.14 if flag(semigroupoids)- build-depends: semigroupoids >=5.3.2 && <5.4+ build-depends: semigroupoids >=6.0.1 && <6.1
src/Data/Crosswalk.hs view
@@ -1,4 +1,3 @@-{-# LANGUAGE CPP #-} {-# LANGUAGE Trustworthy #-} module Data.Crosswalk ( -- * Crosswalk@@ -42,9 +41,7 @@ sequenceL :: (Align f) => t (f a) -> f (t a) sequenceL = crosswalk id -#if __GLASGOW_HASKELL__ >= 707 {-# MINIMAL crosswalk | sequenceL #-}-#endif instance Crosswalk Identity where crosswalk f (Identity a) = fmap Identity (f a)@@ -106,10 +103,7 @@ bisequenceL :: (Align f) => t (f a) (f b) -> f (t a b) bisequenceL = bicrosswalk id id -#if __GLASGOW_HASKELL__ >= 707 {-# MINIMAL bicrosswalk | bisequenceL #-}-#endif- instance Bicrosswalk Either where bicrosswalk f _ (Left x) = Left <$> f x
+ src/Data/Semialign/Indexed.hs view
@@ -0,0 +1,9 @@+{-# LANGUAGE Safe #-}+-- | Zipping and aligning of indexed functors.+module Data.Semialign.Indexed (+ SemialignWithIndex (..),+ ZipWithIndex (..),+ RepeatWithIndex (..),+) where++import Data.Semialign.Internal
src/Data/Semialign/Internal.hs view
@@ -1,18 +1,21 @@ {-# LANGUAGE CPP #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE FunctionalDependencies #-} {-# LANGUAGE GeneralizedNewtypeDeriving #-}+{-# LANGUAGE PolyKinds #-} {-# LANGUAGE StandaloneDeriving #-} {-# LANGUAGE Trustworthy #-}+{-# LANGUAGE UndecidableInstances #-} module Data.Semialign.Internal where import Prelude- (Bool (..), Eq (..), Functor (fmap), Maybe (..), Monad (..), Ord (..),- Ordering (..), String, error, flip, fst, id, maybe, snd, uncurry, ($),- (++), (.))+ (Bool (..), Either (..), Eq (..), Functor (fmap), Int, Maybe (..),+ Monad (..), Ord (..), Ordering (..), String, error, flip, fst, id, maybe,+ snd, uncurry, ($), (++), (.)) import qualified Prelude as Prelude -import Control.Applicative (ZipList (..), pure, (<$>))-import Data.Monoid (Monoid (..))+import Control.Applicative (ZipList (..), pure, (<$>)) import Data.Bifunctor (Bifunctor (..)) import Data.Functor.Compose (Compose (..)) import Data.Functor.Identity (Identity (..))@@ -21,13 +24,18 @@ import Data.HashMap.Strict (HashMap) import Data.List.NonEmpty (NonEmpty (..)) import Data.Maybe (catMaybes)+import Data.Monoid (Monoid (..)) import Data.Proxy (Proxy (..))-import Data.Semigroup (Option (..), Semigroup (..))+import Data.Semigroup (Semigroup (..)) import Data.Sequence (Seq) import Data.Tagged (Tagged (..)) import Data.Vector.Fusion.Stream.Monadic (Step (..), Stream (..)) import Data.Vector.Generic (Vector, empty, stream, unstream)+import Data.Void (Void) +import Data.Functor.WithIndex (FunctorWithIndex (imap))+import Data.Functor.WithIndex.Instances ()+ import qualified Data.HashMap.Strict as HM import qualified Data.List.NonEmpty as NE import qualified Data.Sequence as Seq@@ -35,33 +43,21 @@ import qualified Data.Vector as V import qualified Data.Vector.Fusion.Stream.Monadic as Stream -#if MIN_VERSION_vector(0,11,0) import Data.Vector.Fusion.Bundle.Monadic (Bundle (..)) import qualified Data.Vector.Fusion.Bundle.Monadic as Bundle import qualified Data.Vector.Fusion.Bundle.Size as Bundle-#else-import qualified Data.Vector.Fusion.Stream.Size as Stream-#endif -#if MIN_VERSION_containers(0,5,0) import Data.Map.Lazy (Map) import qualified Data.Map.Lazy as Map import Data.IntMap.Lazy (IntMap) import qualified Data.IntMap.Lazy as IntMap -#if MIN_VERSION_containers(0,5,9) import qualified Data.IntMap.Merge.Lazy as IntMap import qualified Data.Map.Merge.Lazy as Map-#endif --- containers <0.5-#else-import Data.Map (Map)-import qualified Data.Map as Map--import Data.IntMap (IntMap)-import qualified Data.IntMap as IntMap+#if !(MIN_VERSION_base(4,16,0))+import Data.Semigroup (Option (..)) #endif import Data.These@@ -81,7 +77,7 @@ -- 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',+-- And an additional property if @f@ is 'Foldable', -- which tries to enforce 'align'-feel: -- neither values are duplicated nor lost. --@@ -125,17 +121,7 @@ -- ≡ mapMaybe justHere (toList (align x y)) -- @ -------- And an addition property if @f@ is 'Foldable',--- which tries to enforce 'align'-feel:--- neither values are duplicated nor lost.------ @--- toList x = toListOf (folded . here) (align x y)--- = mapMaybe justHere (toList (align x y))--- @----class Functor f => Semialign f where+class Unzip f => Semialign f where -- | Analogous to @'zip'@, combines two structures by taking the union of -- their shapes and using @'These'@ to hold the elements. align :: f a -> f b -> f (These a b)@@ -146,9 +132,7 @@ alignWith :: (These a b -> c) -> f a -> f b -> f c alignWith f a b = f <$> align a b -#if __GLASGOW_HASKELL__ >= 707 {-# MINIMAL (align | alignWith) #-}-#endif -- | A unit of 'align'. --@@ -172,10 +156,18 @@ -- == Laws -- -- @--- uncurry align (unalign xs) ≡ xs -- unalign (align xs ys) ≡ (xs, ys) -- @ --+-- Previously 'Unalign' included a right inverse law+--+-- @+-- uncurry align (unalign xs) ≡ xs+-- @+--+-- But this law was removed in 1.4 to allow list-like instances,+-- where unalign necessarily loses some information.+-- -- == Compatibility note -- -- In version 1 'unalign' was changed to return @(f a, f b)@ pair,@@ -192,11 +184,8 @@ unalignWith :: (c -> These a b) -> f c -> (f a, f b) unalignWith f fx = unalign (fmap f fx) -#if __GLASGOW_HASKELL__ >= 707 {-# MINIMAL unalignWith | unalign #-}-#endif - -- | Functors supporting a 'zip' operation that takes the intersection of -- non-uniform shapes. --@@ -280,9 +269,7 @@ zipWith :: (a -> b -> c) -> f a -> f b -> f c zipWith f a b = uncurry f <$> zip a b -#if __GLASGOW_HASKELL__ >= 707 {-# MINIMAL (zip | zipWith) #-}-#endif -- | Zippable functors supporting left and right units --@@ -316,24 +303,54 @@ -- -- For sequence-like types this holds, but for Map-like it doesn't. ---class Zip f => Unzip f where+class Functor f => Unzip f where unzipWith :: (c -> (a, b)) -> f c -> (f a, f b) unzipWith f = unzip . fmap f unzip :: f (a, b) -> (f a, f b) unzip = unzipWith id -#if __GLASGOW_HASKELL__ >= 707 {-# MINIMAL unzipWith | unzip #-}-#endif unzipDefault :: Functor f => f (a, b) -> (f a, f b) unzipDefault x = (fst <$> x, snd <$> x) +-- | Indexed version of 'Semialign'.+--+-- @since 1.2+class (FunctorWithIndex i f, Semialign f) => SemialignWithIndex i f | f -> i where+ -- | Analogous to 'alignWith', but also provides an index.+ ialignWith :: (i -> These a b -> c) -> f a -> f b -> f c+ ialignWith f a b = imap f (align a b)++-- | Indexed version of 'Zip'.+--+-- @since 1.2+class (SemialignWithIndex i f, Zip f) => ZipWithIndex i f | f -> i where+ -- | Analogous to 'zipWith', but also provides an index.+ izipWith :: (i -> a -> b -> c) -> f a -> f b -> f c+ izipWith f a b = imap (uncurry . f) (zip a b)++-- | Indexed version of 'Repeat'.+--+-- @since 1.2+class (ZipWithIndex i f, Repeat f) => RepeatWithIndex i f | f -> i where+ -- | Analogous to 'repeat', but also provides an index.+ --+ -- This should be the same as 'tabulate' for representable functors.+ irepeat :: (i -> a) -> f a+ irepeat f = imap (\i f' -> f' i) (repeat f)+ ------------------------------------------------------------------------------- -- base ------------------------------------------------------------------------------- +-- |+--+-- @since 1.4+instance Unzip ((->) e) where+ unzip = unzipDefault+ instance Semialign ((->) e) where align f g x = These (f x) (g x) alignWith h f g x = h (These (f x) (g x))@@ -344,6 +361,13 @@ instance Repeat ((->) e) where repeat = pure +instance SemialignWithIndex e ((->) e) where+ ialignWith h f g x = h x (These (f x) (g x))+instance ZipWithIndex e ((->) e) where+ izipWith h f g x = h x (f x) (g x)+instance RepeatWithIndex e ((->) e) where+ irepeat = id+ instance Semialign Maybe where align Nothing Nothing = Nothing align (Just a) Nothing = Just (This a)@@ -370,6 +394,9 @@ instance Align Maybe where nil = Nothing +instance SemialignWithIndex () Maybe+instance ZipWithIndex () Maybe+instance RepeatWithIndex () Maybe instance Semialign [] where align xs [] = This <$> xs@@ -389,7 +416,20 @@ instance Unzip [] where unzip = Prelude.unzip +-- |+--+-- @since 1.4+instance Unalign [] where+ unalign = Prelude.foldr f ([], []) where+ f :: These a b -> ([a], [b]) -> ([a], [b])+ f (This x) ~(xs, ys) = (x : xs, ys)+ f (That y) ~(xs, ys) = ( xs, y : ys)+ f (These x y) ~(xs, ys) = (x : xs, y : ys) +instance SemialignWithIndex Int []+instance ZipWithIndex Int []+instance RepeatWithIndex Int []+ -- | @'zipWith' = 'liftA2'@ . instance Semialign ZipList where alignWith f (ZipList xs) (ZipList ys) = ZipList (alignWith f xs ys)@@ -407,6 +447,14 @@ unzip (ZipList xs) = (ZipList ys, ZipList zs) where (ys, zs) = unzip xs +instance Unalign ZipList where+ unalign (ZipList xs) = (ZipList ys, ZipList zs) where+ (ys, zs) = unalign xs++instance SemialignWithIndex Int ZipList+instance ZipWithIndex Int ZipList+instance RepeatWithIndex Int ZipList+ ------------------------------------------------------------------------------- -- semigroups -------------------------------------------------------------------------------@@ -424,6 +472,11 @@ instance Unzip NonEmpty where unzip = NE.unzip +instance SemialignWithIndex Int NonEmpty+instance ZipWithIndex Int NonEmpty+instance RepeatWithIndex Int NonEmpty++#if !(MIN_VERSION_base(4,16,0)) deriving instance Semialign Option deriving instance Align Option deriving instance Unalign Option@@ -431,6 +484,11 @@ deriving instance Repeat Option deriving instance Unzip Option +-- deriving instance SemialignWithIndex () Option+-- deriving instance ZipWithIndex () Option+-- deriving instance RepeatWithIndex () Option+#endif+ ------------------------------------------------------------------------------- -- containers: ListLike -------------------------------------------------------------------------------@@ -462,17 +520,16 @@ nil = Seq.empty instance Unzip Seq where-#if MIN_VERSION_containers(0,5,11) unzip = Seq.unzip unzipWith = Seq.unzipWith-#else- unzip = unzipDefault-#endif instance Zip Seq where zip = Seq.zip zipWith = Seq.zipWith +instance SemialignWithIndex Int Seq+instance ZipWithIndex Int Seq+ instance Semialign T.Tree where align (T.Node x xs) (T.Node y ys) = T.Node (These x y) (alignWith (these (fmap This) (fmap That) align) xs ys) @@ -493,17 +550,9 @@ ------------------------------------------------------------------------------- instance Ord k => Semialign (Map k) where-#if MIN_VERSION_containers(0,5,9) alignWith f = Map.merge (Map.mapMissing (\_ x -> f (This x))) (Map.mapMissing (\_ y -> f (That y))) (Map.zipWithMatched (\_ x y -> f (These x y)))-#elif MIN_VERSION_containers(0,5,0)- alignWith f = Map.mergeWithKey (\_ x y -> Just $ f $ These x y) (fmap (f . This)) (fmap (f . That))-#else- align m n = Map.unionWith merge (Map.map This m) (Map.map That n)- where merge (This a) (That b) = These a b- merge _ _ = oops "Align Map: merge"-#endif instance (Ord k) => Align (Map k) where nil = Map.empty@@ -517,17 +566,9 @@ zipWith = Map.intersectionWith instance Semialign IntMap where-#if MIN_VERSION_containers(0,5,9) alignWith f = IntMap.merge (IntMap.mapMissing (\_ x -> f (This x))) (IntMap.mapMissing (\_ y -> f (That y))) (IntMap.zipWithMatched (\_ x y -> f (These x y)))-#elif MIN_VERSION_containers(0,5,0)- alignWith f = IntMap.mergeWithKey (\_ x y -> Just $ f $ These x y) (fmap (f . This)) (fmap (f . That))-#else- align m n = IntMap.unionWith merge (IntMap.map This m) (IntMap.map That n)- where merge (This a) (That b) = These a b- merge _ _ = oops "Align IntMap: merge"-#endif instance Align IntMap where nil = IntMap.empty@@ -540,6 +581,13 @@ instance Zip IntMap where zipWith = IntMap.intersectionWith +instance SemialignWithIndex Int IntMap+instance ZipWithIndex Int IntMap where+ izipWith = IntMap.intersectionWithKey+instance Ord k => SemialignWithIndex k (Map k) where+instance Ord k => ZipWithIndex k (Map k) where+ izipWith = Map.intersectionWithKey+ ------------------------------------------------------------------------------- -- transformers -------------------------------------------------------------------------------@@ -556,6 +604,9 @@ instance Unzip Identity where unzip (Identity ~(a, b)) = (Identity a, Identity b) +instance SemialignWithIndex () Identity+instance ZipWithIndex () Identity+instance RepeatWithIndex () Identity instance (Semialign f, Semialign g) => Semialign (Product f g) where align (Pair a b) (Pair c d) = Pair (align a c) (align b d)@@ -581,7 +632,20 @@ ~(al, ar) = unzip a ~(bl, br) = unzip b +instance (SemialignWithIndex i f, SemialignWithIndex j g) => SemialignWithIndex (Either i j) (Product f g) where+ ialignWith f (Pair fa ga) (Pair fb gb) = Pair fc gc where+ fc = ialignWith (f . Left) fa fb+ gc = ialignWith (f . Right) ga gb +instance (ZipWithIndex i f, ZipWithIndex j g) => ZipWithIndex (Either i j) (Product f g) where+ izipWith f (Pair fa ga) (Pair fb gb) = Pair fc gc where+ fc = izipWith (f . Left) fa fb+ gc = izipWith (f . Right) ga gb++instance (RepeatWithIndex i f, RepeatWithIndex j g) => RepeatWithIndex (Either i j) (Product f g) where+ irepeat f = Pair (irepeat (f . Left)) (irepeat (f . Right))++ instance (Semialign f, Semialign g) => Semialign (Compose f g) where alignWith f (Compose x) (Compose y) = Compose (alignWith g x y) where g (This ga) = fmap (f . This) ga@@ -607,22 +671,37 @@ -- unalignWith f (Compose x) = (Compose y, Compose z) where -- ~(y, z) = unalignWith (uncurry These . unalignWith f) x +instance (SemialignWithIndex i f, SemialignWithIndex j g) => SemialignWithIndex (i, j) (Compose f g) where+ ialignWith f (Compose fga) (Compose fgb) = Compose $ ialignWith g fga fgb where+ g i (This ga) = imap (\j -> f (i, j) . This) ga+ g i (That gb) = imap (\j -> f (i, j) . That) gb+ g i (These ga gb) = ialignWith (\j -> f (i, j)) ga gb++instance (ZipWithIndex i f, ZipWithIndex j g) => ZipWithIndex (i, j) (Compose f g) where+ izipWith f (Compose fga) (Compose fgb) = Compose fgc where+ fgc = izipWith (\i -> izipWith (\j -> f (i, j))) fga fgb++instance (RepeatWithIndex i f, RepeatWithIndex j g) => RepeatWithIndex (i, j) (Compose f g) where+ irepeat f = Compose (irepeat (\i -> irepeat (\j -> f (i, j))))+ ------------------------------------------------------------------------------- -- vector ------------------------------------------------------------------------------- -- Based on the Data.Vector.Fusion.Stream.Monadic zipWith implementation++-- |+--+-- @since 1.4+instance Monad m => Unzip (Stream m) where+ unzip = unzipDefault+ instance Monad m => Align (Stream m) where nil = Stream.empty instance Monad m => Semialign (Stream m) where-#if MIN_VERSION_vector(0,11,0) alignWith f (Stream stepa ta) (Stream stepb tb) = Stream step (ta, tb, Nothing, False)-#else- alignWith f (Stream stepa ta na) (Stream stepb tb nb)- = Stream step (ta, tb, Nothing, False) (Stream.larger na nb)-#endif where step (sa, sb, Nothing, False) = do r <- stepa sa@@ -640,23 +719,62 @@ Done -> case (av, adone) of (Just x, False) -> Yield (f $ This x) (sa, sb, Nothing, adone) (_, True) -> Done+#if __GLASGOW_HASKELL__ < 902 _ -> Skip (sa, sb, Nothing, False)+#endif +-- |+--+-- @since 1.4+instance Monad m => Unalign (Stream m) where+ unalign (Stream stepa s) = (Stream stepb s, Stream stepc s)+ where+ stepb i = do+ r <- stepa i+ return $ case r of+ Done -> Done+ Skip j -> Skip j+ Yield (This x) j -> Yield x j+ Yield (These x _) j -> Yield x j+ Yield (That _) j -> Skip j++ stepc i = do+ r <- stepa i+ return $ case r of+ Done -> Done+ Skip j -> Skip j+ Yield (This _) j -> Skip j+ Yield (These _ y) j -> Yield y j+ Yield (That y) j -> Yield y j+ instance Monad m => Zip (Stream m) where zipWith = Stream.zipWith -#if MIN_VERSION_vector(0,11,0)+-- |+--+-- @since 1.4+instance Monad m => Unzip (Bundle m v) where+ unzip = unzipDefault+ instance Monad m => Align (Bundle m v) where nil = Bundle.empty instance Monad m => Semialign (Bundle m v) where alignWith f Bundle{sElems = sa, sSize = na} Bundle{sElems = sb, sSize = nb} = Bundle.fromStream (alignWith f sa sb) (Bundle.larger na nb)-#endif instance Monad m => Zip (Bundle m v) where zipWith = Bundle.zipWith +-- |+--+-- @since 1.4+instance Monad m => Unalign (Bundle m v) where+ unalign Bundle { sElems = xys, sSize = n } =+ (Bundle.fromStream xs (Bundle.toMax n), Bundle.fromStream ys (Bundle.toMax n))+ where+ ~(xs, ys) = unalign xys+ instance Semialign V.Vector where alignWith = alignVectorWith @@ -669,10 +787,22 @@ instance Unzip V.Vector where unzip = V.unzip +-- |+--+-- @since 1.4+instance Unalign V.Vector where+ -- TODO: it would be more efficient to do unalign imperatively.+ unalign xys = (unstream xs, unstream ys) where+ ~(xs, ys) = unalign (stream xys)+ alignVectorWith :: (Vector v a, Vector v b, Vector v c) => (These a b -> c) -> v a -> v b -> v c alignVectorWith f x y = unstream $ alignWith f (stream x) (stream y) +instance SemialignWithIndex Int V.Vector where+instance ZipWithIndex Int V.Vector where+ izipWith = V.izipWith+ ------------------------------------------------------------------------------- -- unordered-containers -------------------------------------------------------------------------------@@ -693,6 +823,10 @@ instance (Eq k, Hashable k) => Unalign (HashMap k) where unalign xs = (HM.mapMaybe justHere xs, HM.mapMaybe justThere xs) +instance (Eq k, Hashable k) => SemialignWithIndex k (HashMap k) where+instance (Eq k, Hashable k) => ZipWithIndex k (HashMap k) where+ izipWith = HM.intersectionWithKey+ ------------------------------------------------------------------------------- -- tagged -------------------------------------------------------------------------------@@ -709,6 +843,9 @@ instance Unzip (Tagged b) where unzip (Tagged ~(a, b)) = (Tagged a, Tagged b) +instance SemialignWithIndex () (Tagged b)+instance ZipWithIndex () (Tagged b)+instance RepeatWithIndex () (Tagged b) instance Semialign Proxy where alignWith _ _ _ = Proxy@@ -729,6 +866,10 @@ instance Unzip Proxy where unzip _ = (Proxy, Proxy)++instance SemialignWithIndex Void Proxy+instance ZipWithIndex Void Proxy+instance RepeatWithIndex Void Proxy ------------------------------------------------------------------------------- -- combinators
src/Data/Zip.hs view
@@ -50,6 +50,4 @@ Zippy f <*> Zippy x = Zippy $ zipWith ($) f x #endif -#if MIN_VERSION_base(4,10,0) liftA2 f (Zippy x) (Zippy y) = Zippy $ zipWith f x y-#endif