packages feed

semialign 1.3.1.1 → 1.4

raw patch · 3 files changed

+97/−4 lines, 3 files

Files

CHANGELOG.md view
@@ -1,3 +1,14 @@+# 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
semialign.cabal view
@@ -1,6 +1,6 @@ cabal-version:      >=1.10 name:               semialign-version:            1.3.1.1+version:            1.4 synopsis:   Align and Zip type-classes from the common Semialign ancestor. 
src/Data/Semialign/Internal.hs view
@@ -121,7 +121,7 @@ --          ≡ 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)@@ -156,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,@@ -295,7 +303,7 @@ -- -- 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 @@ -337,6 +345,12 @@ -- 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))@@ -402,6 +416,16 @@ 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 []@@ -423,6 +447,10 @@     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@@ -661,6 +689,13 @@ -------------------------------------------------------------------------------  -- 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 @@ -688,9 +723,39 @@                     _               -> 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 +-- |+--+-- @since 1.4+instance Monad m => Unzip (Bundle m v) where+    unzip = unzipDefault+ instance Monad m => Align (Bundle m v) where     nil = Bundle.empty @@ -701,6 +766,15 @@ 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 @@ -712,6 +786,14 @@  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