{-# LANGUAGE CPP, DerivingVia, StandaloneDeriving, TypeOperators #-}
module Control.Subcategory.Zip
  ( CZip(..),
    CUnzip(..),
    cunzipDefault,
    CZippy(..),
    CRepeat(..),
    module Control.Subcategory.Semialign
  ) where
import           Control.Applicative                  (ZipList (..))
import           Control.Arrow                        (Arrow ((&&&)), (***))
import           Control.Monad.Zip                    (MonadZip (mzip),
                                                       mzipWith)
import           Control.Subcategory.Functor
import           Control.Subcategory.Semialign
import           Control.Subcategory.Wrapper.Internal
import           Data.Coerce                          (coerce)
import           Data.Containers
import           Data.Functor.Compose                 (Compose (..))
import           Data.Functor.Identity
import qualified Data.Functor.Product                 as SOP
import           Data.Hashable                        (Hashable)
import qualified Data.HashMap.Strict                  as HM
import qualified Data.IntMap.Strict                   as IM
import qualified Data.List.NonEmpty                   as NE
import qualified Data.Map.Strict                      as M
import           Data.MonoTraversable
import qualified Data.Primitive.Array                 as A
import qualified Data.Primitive.PrimArray             as PA
import qualified Data.Primitive.SmallArray            as SA
import           Data.Proxy
import           Data.Semigroup                       (Option (..))
import qualified Data.Sequence                        as Seq
import qualified Data.Sequences                       as MT
import           Data.Tree
import qualified Data.Vector                          as V
import qualified Data.Vector.Generic                  as G
import qualified Data.Vector.Primitive                as Prim
import qualified Data.Vector.Primitive                as PV
import qualified Data.Vector.Storable                 as S
import qualified Data.Vector.Unboxed                  as U
import           Data.Zip
import           GHC.Generics                         ((:*:) (..), (:.:) (..))
import           Prelude                              hiding (repeat, unzip,
                                                       zip, zipWith)
import qualified Prelude                              as P

class CSemialign f => CZip f where
  czipWith
    :: (Dom f a, Dom f b, Dom f c)
    => (a -> b -> c) -> f a -> f b -> f c
  czip
    :: (Dom f a, Dom f b, Dom f (a, b))
    => f a -> f b -> f (a, b)
  {-# INLINE [1] czip #-}
  czip = (a -> b -> (a, b)) -> f a -> f b -> f (a, b)
forall (f :: * -> *) a b c.
(CZip f, Dom f a, Dom f b, Dom f c) =>
(a -> b -> c) -> f a -> f b -> f c
czipWith (,)

instance Zip f => CZip (WrapFunctor f) where
  czip :: WrapFunctor f a -> WrapFunctor f b -> WrapFunctor f (a, b)
czip = WrapFunctor f a -> WrapFunctor f b -> WrapFunctor f (a, b)
forall (f :: * -> *) a b. Zip f => f a -> f b -> f (a, b)
zip
  {-# INLINE [1] czip #-}
  czipWith :: (a -> b -> c)
-> WrapFunctor f a -> WrapFunctor f b -> WrapFunctor f c
czipWith = (a -> b -> c)
-> WrapFunctor f a -> WrapFunctor f b -> WrapFunctor f c
forall (f :: * -> *) a b c.
Zip f =>
(a -> b -> c) -> f a -> f b -> f c
zipWith
  {-# INLINE [1] czipWith #-}

deriving via WrapFunctor [] instance CZip []
deriving via WrapFunctor Maybe instance CZip Maybe
deriving newtype instance CZip Option
deriving via WrapFunctor ZipList instance CZip ZipList
deriving via WrapFunctor Identity instance CZip Identity
deriving via WrapFunctor NE.NonEmpty instance CZip NE.NonEmpty
deriving via WrapFunctor Tree instance CZip Tree
deriving via WrapFunctor ((->) e) instance CZip ((->) e)

#if MIN_VERSION_semialign(1,1,0)
deriving via WrapFunctor Seq.Seq instance CZip Seq.Seq
deriving via WrapFunctor (M.Map k) instance Ord k => CZip (M.Map k)
deriving via WrapFunctor (HM.HashMap k)
  instance (Eq k, Hashable k)
  => CZip (HM.HashMap k)
deriving via WrapFunctor IM.IntMap instance CZip IM.IntMap
#else
instance CZip Seq.Seq where
  czipWith = Seq.zipWith
  {-# INLINE [1] czipWith #-}
  czip = Seq.zip
  {-# INLINE [1] czip #-}
instance Ord k => CZip (M.Map k) where
  czipWith = M.intersectionWith
  {-# INLINE [1] czipWith #-}
instance (Eq k, Hashable k) => CZip (HM.HashMap k) where
  czipWith = HM.intersectionWith
  {-# INLINE [1] czipWith #-}
instance CZip IM.IntMap where
  czipWith = IM.intersectionWith
  {-# INLINE [1] czipWith #-}
#endif


instance CZip V.Vector where
  czip :: Vector a -> Vector b -> Vector (a, b)
czip = Vector a -> Vector b -> Vector (a, b)
forall a b. Vector a -> Vector b -> Vector (a, b)
V.zip
  {-# INLINE [1] czip #-}
  czipWith :: (a -> b -> c) -> Vector a -> Vector b -> Vector c
czipWith = (a -> b -> c) -> Vector a -> Vector b -> Vector c
forall a b c. (a -> b -> c) -> Vector a -> Vector b -> Vector c
V.zipWith
  {-# INLINE [1] czipWith #-}

instance CZip U.Vector where
  czip :: Vector a -> Vector b -> Vector (a, b)
czip = Vector a -> Vector b -> Vector (a, b)
forall a b.
(Unbox a, Unbox b) =>
Vector a -> Vector b -> Vector (a, b)
U.zip
  {-# INLINE [1] czip #-}
  czipWith :: (a -> b -> c) -> Vector a -> Vector b -> Vector c
czipWith = (a -> b -> c) -> Vector a -> Vector b -> Vector c
forall a b c.
(Unbox a, Unbox b, Unbox c) =>
(a -> b -> c) -> Vector a -> Vector b -> Vector c
U.zipWith
  {-# INLINE [1] czipWith #-}

instance CZip S.Vector where
  czipWith :: (a -> b -> c) -> Vector a -> Vector b -> Vector c
czipWith = (a -> b -> c) -> Vector a -> Vector b -> Vector c
forall a b c.
(Storable a, Storable b, Storable c) =>
(a -> b -> c) -> Vector a -> Vector b -> Vector c
S.zipWith
  {-# INLINE [1] czipWith #-}

instance CZip Prim.Vector where
  czipWith :: (a -> b -> c) -> Vector a -> Vector b -> Vector c
czipWith = (a -> b -> c) -> Vector a -> Vector b -> Vector c
forall a b c.
(Prim a, Prim b, Prim c) =>
(a -> b -> c) -> Vector a -> Vector b -> Vector c
Prim.zipWith
  {-# INLINE [1] czipWith #-}

instance CZip Proxy where
  czip :: Proxy a -> Proxy b -> Proxy (a, b)
czip = (Proxy b -> Proxy (a, b)) -> Proxy a -> Proxy b -> Proxy (a, b)
forall a b. a -> b -> a
const ((Proxy b -> Proxy (a, b)) -> Proxy a -> Proxy b -> Proxy (a, b))
-> (Proxy b -> Proxy (a, b)) -> Proxy a -> Proxy b -> Proxy (a, b)
forall a b. (a -> b) -> a -> b
$ Proxy (a, b) -> Proxy b -> Proxy (a, b)
forall a b. a -> b -> a
const Proxy (a, b)
forall k (t :: k). Proxy t
Proxy
  {-# INLINE czip #-}
  czipWith :: (a -> b -> c) -> Proxy a -> Proxy b -> Proxy c
czipWith = (Proxy a -> Proxy b -> Proxy c)
-> (a -> b -> c) -> Proxy a -> Proxy b -> Proxy c
forall a b. a -> b -> a
const ((Proxy a -> Proxy b -> Proxy c)
 -> (a -> b -> c) -> Proxy a -> Proxy b -> Proxy c)
-> (Proxy a -> Proxy b -> Proxy c)
-> (a -> b -> c)
-> Proxy a
-> Proxy b
-> Proxy c
forall a b. (a -> b) -> a -> b
$ (Proxy b -> Proxy c) -> Proxy a -> Proxy b -> Proxy c
forall a b. a -> b -> a
const ((Proxy b -> Proxy c) -> Proxy a -> Proxy b -> Proxy c)
-> (Proxy b -> Proxy c) -> Proxy a -> Proxy b -> Proxy c
forall a b. (a -> b) -> a -> b
$ Proxy c -> Proxy b -> Proxy c
forall a b. a -> b -> a
const Proxy c
forall k (t :: k). Proxy t
Proxy
  {-# INLINE czipWith #-}

instance (CZip f, CZip g) => CZip (SOP.Product f g) where
  czipWith :: (a -> b -> c) -> Product f g a -> Product f g b -> Product f g c
czipWith a -> b -> c
f (SOP.Pair f a
a g a
b) (SOP.Pair f b
c g b
d) =
    f c -> g c -> Product f g c
forall k (f :: k -> *) (g :: k -> *) (a :: k).
f a -> g a -> Product f g a
SOP.Pair ((a -> b -> c) -> f a -> f b -> f c
forall (f :: * -> *) a b c.
(CZip f, Dom f a, Dom f b, Dom f c) =>
(a -> b -> c) -> f a -> f b -> f c
czipWith a -> b -> c
f f a
a f b
c) ((a -> b -> c) -> g a -> g b -> g c
forall (f :: * -> *) a b c.
(CZip f, Dom f a, Dom f b, Dom f c) =>
(a -> b -> c) -> f a -> f b -> f c
czipWith a -> b -> c
f g a
b g b
d)
  {-# INLINE [1] czipWith #-}
  czip :: Product f g a -> Product f g b -> Product f g (a, b)
czip (SOP.Pair f a
a g a
b) (SOP.Pair f b
c g b
d) =
    f (a, b) -> g (a, b) -> Product f g (a, b)
forall k (f :: k -> *) (g :: k -> *) (a :: k).
f a -> g a -> Product f g a
SOP.Pair (f a -> f b -> f (a, b)
forall (f :: * -> *) a b.
(CZip f, Dom f a, Dom f b, Dom f (a, b)) =>
f a -> f b -> f (a, b)
czip f a
a f b
c) (g a -> g b -> g (a, b)
forall (f :: * -> *) a b.
(CZip f, Dom f a, Dom f b, Dom f (a, b)) =>
f a -> f b -> f (a, b)
czip g a
b g b
d)
  {-# INLINE [1] czip #-}

instance (CZip f, CZip g) => CZip (f :*: g) where
  czipWith :: (a -> b -> c) -> (:*:) f g a -> (:*:) f g b -> (:*:) f g c
czipWith a -> b -> c
f (f a
a :*: g a
b) (f b
c :*: g b
d) =
    (a -> b -> c) -> f a -> f b -> f c
forall (f :: * -> *) a b c.
(CZip f, Dom f a, Dom f b, Dom f c) =>
(a -> b -> c) -> f a -> f b -> f c
czipWith a -> b -> c
f f a
a f b
c f c -> g c -> (:*:) f g c
forall k (f :: k -> *) (g :: k -> *) (p :: k).
f p -> g p -> (:*:) f g p
:*: (a -> b -> c) -> g a -> g b -> g c
forall (f :: * -> *) a b c.
(CZip f, Dom f a, Dom f b, Dom f c) =>
(a -> b -> c) -> f a -> f b -> f c
czipWith a -> b -> c
f g a
b g b
d
  {-# INLINE [1] czipWith #-}
  czip :: (:*:) f g a -> (:*:) f g b -> (:*:) f g (a, b)
czip (f a
a :*: g a
b) (f b
c :*: g b
d) =
    f a -> f b -> f (a, b)
forall (f :: * -> *) a b.
(CZip f, Dom f a, Dom f b, Dom f (a, b)) =>
f a -> f b -> f (a, b)
czip f a
a f b
c f (a, b) -> g (a, b) -> (:*:) f g (a, b)
forall k (f :: k -> *) (g :: k -> *) (p :: k).
f p -> g p -> (:*:) f g p
:*: g a -> g b -> g (a, b)
forall (f :: * -> *) a b.
(CZip f, Dom f a, Dom f b, Dom f (a, b)) =>
f a -> f b -> f (a, b)
czip g a
b g b
d
  {-# INLINE [1] czip #-}

instance (CZip f, CZip g) => CZip (Compose f g) where
  czipWith :: (a -> b -> c) -> Compose f g a -> Compose f g b -> Compose f g c
czipWith a -> b -> c
f (Compose f (g a)
a) (Compose f (g b)
b) =
    f (g c) -> Compose f g c
forall k k1 (f :: k -> *) (g :: k1 -> k) (a :: k1).
f (g a) -> Compose f g a
Compose (f (g c) -> Compose f g c) -> f (g c) -> Compose f g c
forall a b. (a -> b) -> a -> b
$ (g a -> g b -> g c) -> f (g a) -> f (g b) -> f (g c)
forall (f :: * -> *) a b c.
(CZip f, Dom f a, Dom f b, Dom f c) =>
(a -> b -> c) -> f a -> f b -> f c
czipWith ((a -> b -> c) -> g a -> g b -> g c
forall (f :: * -> *) a b c.
(CZip f, Dom f a, Dom f b, Dom f c) =>
(a -> b -> c) -> f a -> f b -> f c
czipWith a -> b -> c
f) f (g a)
a f (g b)
b
  {-# INLINE [1] czipWith #-}
  czip :: Compose f g a -> Compose f g b -> Compose f g (a, b)
czip (Compose f (g a)
a) (Compose f (g b)
b) =
    f (g (a, b)) -> Compose f g (a, b)
forall k k1 (f :: k -> *) (g :: k1 -> k) (a :: k1).
f (g a) -> Compose f g a
Compose (f (g (a, b)) -> Compose f g (a, b))
-> f (g (a, b)) -> Compose f g (a, b)
forall a b. (a -> b) -> a -> b
$ (g a -> g b -> g (a, b)) -> f (g a) -> f (g b) -> f (g (a, b))
forall (f :: * -> *) a b c.
(CZip f, Dom f a, Dom f b, Dom f c) =>
(a -> b -> c) -> f a -> f b -> f c
czipWith g a -> g b -> g (a, b)
forall (f :: * -> *) a b.
(CZip f, Dom f a, Dom f b, Dom f (a, b)) =>
f a -> f b -> f (a, b)
czip f (g a)
a f (g b)
b
  {-# INLINE [1] czip #-}

instance (CZip f, CZip g) => CZip (f :.: g) where
  czipWith :: (a -> b -> c) -> (:.:) f g a -> (:.:) f g b -> (:.:) f g c
czipWith a -> b -> c
f (Comp1 f (g a)
a) (Comp1 f (g b)
b) =
    f (g c) -> (:.:) f g c
forall k2 k1 (f :: k2 -> *) (g :: k1 -> k2) (p :: k1).
f (g p) -> (:.:) f g p
Comp1 (f (g c) -> (:.:) f g c) -> f (g c) -> (:.:) f g c
forall a b. (a -> b) -> a -> b
$ (g a -> g b -> g c) -> f (g a) -> f (g b) -> f (g c)
forall (f :: * -> *) a b c.
(CZip f, Dom f a, Dom f b, Dom f c) =>
(a -> b -> c) -> f a -> f b -> f c
czipWith ((a -> b -> c) -> g a -> g b -> g c
forall (f :: * -> *) a b c.
(CZip f, Dom f a, Dom f b, Dom f c) =>
(a -> b -> c) -> f a -> f b -> f c
czipWith a -> b -> c
f) f (g a)
a f (g b)
b
  {-# INLINE [1] czipWith #-}
  czip :: (:.:) f g a -> (:.:) f g b -> (:.:) f g (a, b)
czip (Comp1 f (g a)
a) (Comp1 f (g b)
b) =
    f (g (a, b)) -> (:.:) f g (a, b)
forall k2 k1 (f :: k2 -> *) (g :: k1 -> k2) (p :: k1).
f (g p) -> (:.:) f g p
Comp1 (f (g (a, b)) -> (:.:) f g (a, b))
-> f (g (a, b)) -> (:.:) f g (a, b)
forall a b. (a -> b) -> a -> b
$ (g a -> g b -> g (a, b)) -> f (g a) -> f (g b) -> f (g (a, b))
forall (f :: * -> *) a b c.
(CZip f, Dom f a, Dom f b, Dom f c) =>
(a -> b -> c) -> f a -> f b -> f c
czipWith g a -> g b -> g (a, b)
forall (f :: * -> *) a b.
(CZip f, Dom f a, Dom f b, Dom f (a, b)) =>
f a -> f b -> f (a, b)
czip f (g a)
a f (g b)
b
  {-# INLINE [1] czip #-}

{-# RULES
"czip/List"
  czip = P.zip
"czipWith/List"
  czipWith = P.zipWith
"czip/NonEmpty"
  czip = NE.zip
"czipWith/NonEmpty"
  czipWith = NE.zipWith
"czip/Seq"
  czip = Seq.zip
"czipWith/Seq"
  czipWith = Seq.zipWith
  #-}

class CZip f => CRepeat f where
  crepeat :: Dom f a => a -> f a

newtype CZippy f a = CZippy { CZippy f a -> f a
runCZippy :: f a }
  deriving (Int -> CZippy f a -> ShowS
[CZippy f a] -> ShowS
CZippy f a -> String
(Int -> CZippy f a -> ShowS)
-> (CZippy f a -> String)
-> ([CZippy f a] -> ShowS)
-> Show (CZippy f a)
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
forall k (f :: k -> *) (a :: k).
Show (f a) =>
Int -> CZippy f a -> ShowS
forall k (f :: k -> *) (a :: k).
Show (f a) =>
[CZippy f a] -> ShowS
forall k (f :: k -> *) (a :: k). Show (f a) => CZippy f a -> String
showList :: [CZippy f a] -> ShowS
$cshowList :: forall k (f :: k -> *) (a :: k).
Show (f a) =>
[CZippy f a] -> ShowS
show :: CZippy f a -> String
$cshow :: forall k (f :: k -> *) (a :: k). Show (f a) => CZippy f a -> String
showsPrec :: Int -> CZippy f a -> ShowS
$cshowsPrec :: forall k (f :: k -> *) (a :: k).
Show (f a) =>
Int -> CZippy f a -> ShowS
Show, ReadPrec [CZippy f a]
ReadPrec (CZippy f a)
Int -> ReadS (CZippy f a)
ReadS [CZippy f a]
(Int -> ReadS (CZippy f a))
-> ReadS [CZippy f a]
-> ReadPrec (CZippy f a)
-> ReadPrec [CZippy f a]
-> Read (CZippy f a)
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
forall k (f :: k -> *) (a :: k).
Read (f a) =>
ReadPrec [CZippy f a]
forall k (f :: k -> *) (a :: k).
Read (f a) =>
ReadPrec (CZippy f a)
forall k (f :: k -> *) (a :: k).
Read (f a) =>
Int -> ReadS (CZippy f a)
forall k (f :: k -> *) (a :: k). Read (f a) => ReadS [CZippy f a]
readListPrec :: ReadPrec [CZippy f a]
$creadListPrec :: forall k (f :: k -> *) (a :: k).
Read (f a) =>
ReadPrec [CZippy f a]
readPrec :: ReadPrec (CZippy f a)
$creadPrec :: forall k (f :: k -> *) (a :: k).
Read (f a) =>
ReadPrec (CZippy f a)
readList :: ReadS [CZippy f a]
$creadList :: forall k (f :: k -> *) (a :: k). Read (f a) => ReadS [CZippy f a]
readsPrec :: Int -> ReadS (CZippy f a)
$creadsPrec :: forall k (f :: k -> *) (a :: k).
Read (f a) =>
Int -> ReadS (CZippy f a)
Read)
  deriving newtype (a -> CZippy f b -> CZippy f a
(a -> b) -> CZippy f a -> CZippy f b
(forall a b. (a -> b) -> CZippy f a -> CZippy f b)
-> (forall a b. a -> CZippy f b -> CZippy f a)
-> Functor (CZippy f)
forall a b. a -> CZippy f b -> CZippy f a
forall a b. (a -> b) -> CZippy f a -> CZippy f b
forall (f :: * -> *) a b.
Functor f =>
a -> CZippy f b -> CZippy f a
forall (f :: * -> *) a b.
Functor f =>
(a -> b) -> CZippy f a -> CZippy f b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
<$ :: a -> CZippy f b -> CZippy f a
$c<$ :: forall (f :: * -> *) a b.
Functor f =>
a -> CZippy f b -> CZippy f a
fmap :: (a -> b) -> CZippy f a -> CZippy f b
$cfmap :: forall (f :: * -> *) a b.
Functor f =>
(a -> b) -> CZippy f a -> CZippy f b
Functor, Semialign (CZippy f)
Semialign (CZippy f)
-> (forall a b. CZippy f a -> CZippy f b -> CZippy f (a, b))
-> (forall a b c.
    (a -> b -> c) -> CZippy f a -> CZippy f b -> CZippy f c)
-> Zip (CZippy f)
CZippy f a -> CZippy f b -> CZippy f (a, b)
(a -> b -> c) -> CZippy f a -> CZippy f b -> CZippy f c
forall a b. CZippy f a -> CZippy f b -> CZippy f (a, b)
forall a b c.
(a -> b -> c) -> CZippy f a -> CZippy f b -> CZippy f c
forall (f :: * -> *).
Semialign f
-> (forall a b. f a -> f b -> f (a, b))
-> (forall a b c. (a -> b -> c) -> f a -> f b -> f c)
-> Zip f
forall (f :: * -> *). Zip f => Semialign (CZippy f)
forall (f :: * -> *) a b.
Zip f =>
CZippy f a -> CZippy f b -> CZippy f (a, b)
forall (f :: * -> *) a b c.
Zip f =>
(a -> b -> c) -> CZippy f a -> CZippy f b -> CZippy f c
zipWith :: (a -> b -> c) -> CZippy f a -> CZippy f b -> CZippy f c
$czipWith :: forall (f :: * -> *) a b c.
Zip f =>
(a -> b -> c) -> CZippy f a -> CZippy f b -> CZippy f c
zip :: CZippy f a -> CZippy f b -> CZippy f (a, b)
$czip :: forall (f :: * -> *) a b.
Zip f =>
CZippy f a -> CZippy f b -> CZippy f (a, b)
$cp1Zip :: forall (f :: * -> *). Zip f => Semialign (CZippy f)
Zip, Functor (CZippy f)
Functor (CZippy f)
-> (forall a b. CZippy f a -> CZippy f b -> CZippy f (These a b))
-> (forall a b c.
    (These a b -> c) -> CZippy f a -> CZippy f b -> CZippy f c)
-> Semialign (CZippy f)
CZippy f a -> CZippy f b -> CZippy f (These a b)
(These a b -> c) -> CZippy f a -> CZippy f b -> CZippy f c
forall a b. CZippy f a -> CZippy f b -> CZippy f (These a b)
forall a b c.
(These a b -> c) -> CZippy f a -> CZippy f b -> CZippy f c
forall (f :: * -> *).
Functor f
-> (forall a b. f a -> f b -> f (These a b))
-> (forall a b c. (These a b -> c) -> f a -> f b -> f c)
-> Semialign f
forall (f :: * -> *). Semialign f => Functor (CZippy f)
forall (f :: * -> *) a b.
Semialign f =>
CZippy f a -> CZippy f b -> CZippy f (These a b)
forall (f :: * -> *) a b c.
Semialign f =>
(These a b -> c) -> CZippy f a -> CZippy f b -> CZippy f c
alignWith :: (These a b -> c) -> CZippy f a -> CZippy f b -> CZippy f c
$calignWith :: forall (f :: * -> *) a b c.
Semialign f =>
(These a b -> c) -> CZippy f a -> CZippy f b -> CZippy f c
align :: CZippy f a -> CZippy f b -> CZippy f (These a b)
$calign :: forall (f :: * -> *) a b.
Semialign f =>
CZippy f a -> CZippy f b -> CZippy f (These a b)
$cp1Semialign :: forall (f :: * -> *). Semialign f => Functor (CZippy f)
Semialign, CZippy f a -> CZippy f a -> Bool
(CZippy f a -> CZippy f a -> Bool)
-> (CZippy f a -> CZippy f a -> Bool) -> Eq (CZippy f a)
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
forall k (f :: k -> *) (a :: k).
Eq (f a) =>
CZippy f a -> CZippy f a -> Bool
/= :: CZippy f a -> CZippy f a -> Bool
$c/= :: forall k (f :: k -> *) (a :: k).
Eq (f a) =>
CZippy f a -> CZippy f a -> Bool
== :: CZippy f a -> CZippy f a -> Bool
$c== :: forall k (f :: k -> *) (a :: k).
Eq (f a) =>
CZippy f a -> CZippy f a -> Bool
Eq, Eq (CZippy f a)
Eq (CZippy f a)
-> (CZippy f a -> CZippy f a -> Ordering)
-> (CZippy f a -> CZippy f a -> Bool)
-> (CZippy f a -> CZippy f a -> Bool)
-> (CZippy f a -> CZippy f a -> Bool)
-> (CZippy f a -> CZippy f a -> Bool)
-> (CZippy f a -> CZippy f a -> CZippy f a)
-> (CZippy f a -> CZippy f a -> CZippy f a)
-> Ord (CZippy f a)
CZippy f a -> CZippy f a -> Bool
CZippy f a -> CZippy f a -> Ordering
CZippy f a -> CZippy f a -> CZippy f a
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
forall k (f :: k -> *) (a :: k). Ord (f a) => Eq (CZippy f a)
forall k (f :: k -> *) (a :: k).
Ord (f a) =>
CZippy f a -> CZippy f a -> Bool
forall k (f :: k -> *) (a :: k).
Ord (f a) =>
CZippy f a -> CZippy f a -> Ordering
forall k (f :: k -> *) (a :: k).
Ord (f a) =>
CZippy f a -> CZippy f a -> CZippy f a
min :: CZippy f a -> CZippy f a -> CZippy f a
$cmin :: forall k (f :: k -> *) (a :: k).
Ord (f a) =>
CZippy f a -> CZippy f a -> CZippy f a
max :: CZippy f a -> CZippy f a -> CZippy f a
$cmax :: forall k (f :: k -> *) (a :: k).
Ord (f a) =>
CZippy f a -> CZippy f a -> CZippy f a
>= :: CZippy f a -> CZippy f a -> Bool
$c>= :: forall k (f :: k -> *) (a :: k).
Ord (f a) =>
CZippy f a -> CZippy f a -> Bool
> :: CZippy f a -> CZippy f a -> Bool
$c> :: forall k (f :: k -> *) (a :: k).
Ord (f a) =>
CZippy f a -> CZippy f a -> Bool
<= :: CZippy f a -> CZippy f a -> Bool
$c<= :: forall k (f :: k -> *) (a :: k).
Ord (f a) =>
CZippy f a -> CZippy f a -> Bool
< :: CZippy f a -> CZippy f a -> Bool
$c< :: forall k (f :: k -> *) (a :: k).
Ord (f a) =>
CZippy f a -> CZippy f a -> Bool
compare :: CZippy f a -> CZippy f a -> Ordering
$ccompare :: forall k (f :: k -> *) (a :: k).
Ord (f a) =>
CZippy f a -> CZippy f a -> Ordering
$cp1Ord :: forall k (f :: k -> *) (a :: k). Ord (f a) => Eq (CZippy f a)
Ord)
  deriving newtype (Constrained (CZippy f)
forall (f :: * -> *). Constrained f
Constrained)
#if MIN_VERSION_semialign(1,1,0)
  deriving newtype (Zip (CZippy f)
a -> CZippy f a
Zip (CZippy f) -> (forall a. a -> CZippy f a) -> Repeat (CZippy f)
forall a. a -> CZippy f a
forall (f :: * -> *). Zip f -> (forall a. a -> f a) -> Repeat f
forall (f :: * -> *). Repeat f => Zip (CZippy f)
forall (f :: * -> *) a. Repeat f => a -> CZippy f a
repeat :: a -> CZippy f a
$crepeat :: forall (f :: * -> *) a. Repeat f => a -> CZippy f a
$cp1Repeat :: forall (f :: * -> *). Repeat f => Zip (CZippy f)
Repeat)
#endif

instance CFunctor f => CFunctor (CZippy f) where
  cmap :: (a -> b) -> CZippy f a -> CZippy f b
cmap = ((a -> b) -> f a -> f b) -> (a -> b) -> CZippy f a -> CZippy f b
coerce (((a -> b) -> f a -> f b) -> (a -> b) -> CZippy f a -> CZippy f b)
-> ((a -> b) -> f a -> f b) -> (a -> b) -> CZippy f a -> CZippy f b
forall a b. (a -> b) -> a -> b
$ (Dom f a, Dom f b) => (a -> b) -> f a -> f b
forall (f :: * -> *) a b.
(CFunctor f, Dom f a, Dom f b) =>
(a -> b) -> f a -> f b
cmap @f @a @b
    :: forall a b. (Dom f a, Dom f b) => (a -> b) -> CZippy f a -> CZippy f b
  {-# INLINE [1] cmap #-}

instance CSemialign f => CSemialign (CZippy f) where
  calignWith :: (These a b -> c) -> CZippy f a -> CZippy f b -> CZippy f c
calignWith = \These a b -> c
f -> (f a -> f b -> f c) -> CZippy f a -> CZippy f b -> CZippy f c
coerce ((f a -> f b -> f c) -> CZippy f a -> CZippy f b -> CZippy f c)
-> (f a -> f b -> f c) -> CZippy f a -> CZippy f b -> CZippy f c
forall a b. (a -> b) -> a -> b
$ (These a b -> c) -> f a -> f b -> f c
forall (f :: * -> *) a b c.
(CSemialign f, Dom f a, Dom f b, Dom f c) =>
(These a b -> c) -> f a -> f b -> f c
calignWith @f These a b -> c
f
  {-# INLINE [1] calignWith #-}

instance CZip f => CZip (CZippy f) where
  czipWith :: (a -> b -> c) -> CZippy f a -> CZippy f b -> CZippy f c
czipWith a -> b -> c
f = (f a -> f b -> f c) -> CZippy f a -> CZippy f b -> CZippy f c
coerce ((f a -> f b -> f c) -> CZippy f a -> CZippy f b -> CZippy f c)
-> (f a -> f b -> f c) -> CZippy f a -> CZippy f b -> CZippy f c
forall a b. (a -> b) -> a -> b
$ (a -> b -> c) -> f a -> f b -> f c
forall (f :: * -> *) a b c.
(CZip f, Dom f a, Dom f b, Dom f c) =>
(a -> b -> c) -> f a -> f b -> f c
czipWith @f a -> b -> c
f
  {-# INLINE [1] czipWith #-}

instance CRepeat f => CRepeat (CZippy f) where
  crepeat :: a -> CZippy f a
crepeat = f a -> CZippy f a
forall k (f :: k -> *) (a :: k). f a -> CZippy f a
CZippy (f a -> CZippy f a) -> (a -> f a) -> a -> CZippy f a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> f a
forall (f :: * -> *) a. (CRepeat f, Dom f a) => a -> f a
crepeat
  {-# INLINE [1] crepeat #-}

instance (CZip f, Dom f a, Semigroup a) => Semigroup (CZippy f a) where
  <> :: CZippy f a -> CZippy f a -> CZippy f a
(<>) = (f a -> f a -> f a) -> CZippy f a -> CZippy f a -> CZippy f a
coerce ((f a -> f a -> f a) -> CZippy f a -> CZippy f a -> CZippy f a)
-> (f a -> f a -> f a) -> CZippy f a -> CZippy f a -> CZippy f a
forall a b. (a -> b) -> a -> b
$ (a -> a -> a) -> f a -> f a -> f a
forall (f :: * -> *) a b c.
(CZip f, Dom f a, Dom f b, Dom f c) =>
(a -> b -> c) -> f a -> f b -> f c
czipWith @f (Semigroup a => a -> a -> a
forall a. Semigroup a => a -> a -> a
(<>) @a)
  {-# INLINE [1] (<>) #-}

instance (CRepeat f, Dom f a, Monoid a) => Monoid (CZippy f a) where
  mempty :: CZippy f a
mempty = f a -> CZippy f a
coerce (f a -> CZippy f a) -> f a -> CZippy f a
forall a b. (a -> b) -> a -> b
$ a -> f a
forall (f :: * -> *) a. (CRepeat f, Dom f a) => a -> f a
crepeat @f (Monoid a => a
forall a. Monoid a => a
mempty @a)
  {-# INLINE [1] mempty #-}

#if MIN_VERSION_semialign(1,1,0)
instance Repeat f => CRepeat (WrapFunctor f) where
  crepeat :: a -> WrapFunctor f a
crepeat = (a -> f a) -> a -> WrapFunctor f a
coerce ((a -> f a) -> a -> WrapFunctor f a)
-> (a -> f a) -> a -> WrapFunctor f a
forall a b. (a -> b) -> a -> b
$ a -> f a
forall (f :: * -> *) a. Repeat f => a -> f a
repeat @f @a
    :: forall a. a -> WrapFunctor f a
  {-# INLINE [1] crepeat #-}
deriving via WrapFunctor [] instance CRepeat []
deriving via WrapFunctor Maybe instance CRepeat Maybe
deriving newtype instance CRepeat Option
deriving via WrapFunctor ZipList instance CRepeat ZipList
deriving via WrapFunctor Identity instance CRepeat Identity
deriving via WrapFunctor NE.NonEmpty instance CRepeat NE.NonEmpty
deriving via WrapFunctor Tree instance CRepeat Tree
deriving via WrapFunctor ((->) e) instance CRepeat ((->) e)
#else
instance CRepeat [] where
  crepeat = P.repeat
  {-# INLINE [1] crepeat #-}
instance CRepeat Maybe where
  crepeat = Just
  {-# INLINE [1] crepeat #-}
deriving newtype instance CRepeat Option
deriving newtype instance CRepeat ZipList
instance CRepeat Identity where
  crepeat = Identity
  {-# INLINE [1] crepeat #-}
instance CRepeat NE.NonEmpty where
  crepeat = NE.repeat
  {-# INLINE [1] crepeat #-}
instance CRepeat Tree where
  crepeat x = n where n = Node x (P.repeat n)
  {-# INLINE [1] crepeat #-}
instance CRepeat Proxy where
  crepeat = const Proxy
  {-# INLINE [1] crepeat #-}
instance CRepeat ((->) e) where
  crepeat = const
  {-# INLINE [1] crepeat #-}
#endif

instance CZip SA.SmallArray where
  czip :: SmallArray a -> SmallArray b -> SmallArray (a, b)
czip = SmallArray a -> SmallArray b -> SmallArray (a, b)
forall (m :: * -> *) a b. MonadZip m => m a -> m b -> m (a, b)
mzip
  {-# INLINE [1] czip #-}
  czipWith :: (a -> b -> c) -> SmallArray a -> SmallArray b -> SmallArray c
czipWith = (a -> b -> c) -> SmallArray a -> SmallArray b -> SmallArray c
forall (m :: * -> *) a b c.
MonadZip m =>
(a -> b -> c) -> m a -> m b -> m c
mzipWith
  {-# INLINE [1] czipWith #-}

instance CZip A.Array where
  czip :: Array a -> Array b -> Array (a, b)
czip = Array a -> Array b -> Array (a, b)
forall (m :: * -> *) a b. MonadZip m => m a -> m b -> m (a, b)
mzip
  {-# INLINE [1] czip #-}
  czipWith :: (a -> b -> c) -> Array a -> Array b -> Array c
czipWith = (a -> b -> c) -> Array a -> Array b -> Array c
forall (m :: * -> *) a b c.
MonadZip m =>
(a -> b -> c) -> m a -> m b -> m c
mzipWith
  {-# INLINE [1] czipWith #-}

instance CZip PA.PrimArray where
  czipWith :: (a -> b -> c) -> PrimArray a -> PrimArray b -> PrimArray c
czipWith a -> b -> c
f PrimArray a
l PrimArray b
r =
    Int -> (Int -> c) -> PrimArray c
forall a. Prim a => Int -> (Int -> a) -> PrimArray a
PA.generatePrimArray
      (PrimArray a -> Int
forall a. Prim a => PrimArray a -> Int
PA.sizeofPrimArray PrimArray a
l Int -> Int -> Int
forall a. Ord a => a -> a -> a
`min` PrimArray b -> Int
forall a. Prim a => PrimArray a -> Int
PA.sizeofPrimArray PrimArray b
r) ((Int -> c) -> PrimArray c) -> (Int -> c) -> PrimArray c
forall a b. (a -> b) -> a -> b
$ \Int
n ->
        a -> b -> c
f (PrimArray a -> Int -> a
forall a. Prim a => PrimArray a -> Int -> a
PA.indexPrimArray PrimArray a
l Int
n) (PrimArray b -> Int -> b
forall a. Prim a => PrimArray a -> Int -> a
PA.indexPrimArray PrimArray b
r Int
n)
  {-# INLINE [1] czipWith #-}

class CZip f => CUnzip f where
  cunzip
    :: (Dom f (a, b), Dom f a, Dom f b)
    => f (a, b) -> (f a, f b)
  {-# INLINE [1] cunzip #-}
  cunzip = ((a, b) -> (a, b)) -> f (a, b) -> (f a, f b)
forall (f :: * -> *) c a b.
(CUnzip f, Dom f c, Dom f a, Dom f b) =>
(c -> (a, b)) -> f c -> (f a, f b)
cunzipWith (a, b) -> (a, b)
forall a. a -> a
id

  cunzipWith
    :: (Dom f c, Dom f a, Dom f b)
    => (c -> (a, b)) -> f c -> (f a, f b)

cunzipDefault
  :: (CFunctor f, Dom f (a, b), Dom f a, Dom f b)
  => f (a, b) -> (f a, f b)
{-# INLINE cunzipDefault #-}
cunzipDefault :: f (a, b) -> (f a, f b)
cunzipDefault = ((a, b) -> a) -> f (a, b) -> f a
forall (f :: * -> *) a b.
(CFunctor f, Dom f a, Dom f b) =>
(a -> b) -> f a -> f b
cmap (a, b) -> a
forall a b. (a, b) -> a
fst (f (a, b) -> f a) -> (f (a, b) -> f b) -> f (a, b) -> (f a, f b)
forall (a :: * -> * -> *) b c c'.
Arrow a =>
a b c -> a b c' -> a b (c, c')
&&& ((a, b) -> b) -> f (a, b) -> f b
forall (f :: * -> *) a b.
(CFunctor f, Dom f a, Dom f b) =>
(a -> b) -> f a -> f b
cmap (a, b) -> b
forall a b. (a, b) -> b
snd

#if MIN_VERSION_semialign(1,1,0)
instance Unzip f => CUnzip (WrapFunctor f) where
#else
instance (Zip f, Unzip f) => CUnzip (WrapFunctor f) where
#endif
  cunzip :: forall a b. WrapFunctor f (a, b) -> (WrapFunctor f a, WrapFunctor f b)
  {-# INLINE cunzip #-}
  cunzip :: WrapFunctor f (a, b) -> (WrapFunctor f a, WrapFunctor f b)
cunzip = (f (a, b) -> (f a, f b))
-> WrapFunctor f (a, b) -> (WrapFunctor f a, WrapFunctor f b)
coerce ((f (a, b) -> (f a, f b))
 -> WrapFunctor f (a, b) -> (WrapFunctor f a, WrapFunctor f b))
-> (f (a, b) -> (f a, f b))
-> WrapFunctor f (a, b)
-> (WrapFunctor f a, WrapFunctor f b)
forall a b. (a -> b) -> a -> b
$ f (a, b) -> (f a, f b)
forall (f :: * -> *) a b. Unzip f => f (a, b) -> (f a, f b)
unzip @f @a @b
  {-# INLINE cunzipWith #-}
  cunzipWith :: (c -> (a, b))
-> WrapFunctor f c -> (WrapFunctor f a, WrapFunctor f b)
cunzipWith = ((c -> (a, b)) -> f c -> (f a, f b))
-> (c -> (a, b))
-> WrapFunctor f c
-> (WrapFunctor f a, WrapFunctor f b)
coerce (((c -> (a, b)) -> f c -> (f a, f b))
 -> (c -> (a, b))
 -> WrapFunctor f c
 -> (WrapFunctor f a, WrapFunctor f b))
-> ((c -> (a, b)) -> f c -> (f a, f b))
-> (c -> (a, b))
-> WrapFunctor f c
-> (WrapFunctor f a, WrapFunctor f b)
forall a b. (a -> b) -> a -> b
$ (c -> (a, b)) -> f c -> (f a, f b)
forall (f :: * -> *) c a b.
Unzip f =>
(c -> (a, b)) -> f c -> (f a, f b)
unzipWith @f @c @a @b
    :: forall a b c. (c -> (a, b)) -> WrapFunctor f c -> (WrapFunctor f a, WrapFunctor f b)

instance CUnzip [] where
  cunzip :: [(a, b)] -> ([a], [b])
cunzip = [(a, b)] -> ([a], [b])
forall a b. [(a, b)] -> ([a], [b])
P.unzip
  {-# INLINE [1] cunzip #-}
  cunzipWith :: (c -> (a, b)) -> [c] -> ([a], [b])
cunzipWith = \c -> (a, b)
f -> [(a, b)] -> ([a], [b])
forall a b. [(a, b)] -> ([a], [b])
P.unzip ([(a, b)] -> ([a], [b])) -> ([c] -> [(a, b)]) -> [c] -> ([a], [b])
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (c -> (a, b)) -> [c] -> [(a, b)]
forall a b. (a -> b) -> [a] -> [b]
map c -> (a, b)
f
  {-# INLINE [1] cunzipWith #-}

deriving via WrapFunctor Maybe instance CUnzip Maybe
#if MIN_VERSION_semialign(1,1,0)
deriving via WrapFunctor Option instance CUnzip Option
#endif
deriving via [] instance CUnzip ZipList
deriving via WrapFunctor Identity instance CUnzip Identity
deriving via WrapFunctor NE.NonEmpty instance CUnzip NE.NonEmpty
deriving via WrapFunctor Tree instance CUnzip Tree
instance CUnzip V.Vector where
  cunzip :: Vector (a, b) -> (Vector a, Vector b)
cunzip = Vector (a, b) -> (Vector a, Vector b)
forall a b. Vector (a, b) -> (Vector a, Vector b)
V.unzip
  {-# INLINE [1] cunzip #-}
  cunzipWith :: (c -> (a, b)) -> Vector c -> (Vector a, Vector b)
cunzipWith = \c -> (a, b)
f -> Vector (a, b) -> (Vector a, Vector b)
forall a b. Vector (a, b) -> (Vector a, Vector b)
V.unzip (Vector (a, b) -> (Vector a, Vector b))
-> (Vector c -> Vector (a, b)) -> Vector c -> (Vector a, Vector b)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (c -> (a, b)) -> Vector c -> Vector (a, b)
forall a b. (a -> b) -> Vector a -> Vector b
V.map c -> (a, b)
f
  {-# INLINE [1] cunzipWith #-}
instance CUnzip U.Vector where
  cunzip :: Vector (a, b) -> (Vector a, Vector b)
cunzip = Vector (a, b) -> (Vector a, Vector b)
forall a b.
(Unbox a, Unbox b) =>
Vector (a, b) -> (Vector a, Vector b)
U.unzip
  {-# INLINE [1] cunzip #-}
  cunzipWith :: (c -> (a, b)) -> Vector c -> (Vector a, Vector b)
cunzipWith = \c -> (a, b)
f -> Vector (a, b) -> (Vector a, Vector b)
forall a b.
(Unbox a, Unbox b) =>
Vector (a, b) -> (Vector a, Vector b)
U.unzip (Vector (a, b) -> (Vector a, Vector b))
-> (Vector c -> Vector (a, b)) -> Vector c -> (Vector a, Vector b)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (c -> (a, b)) -> Vector c -> Vector (a, b)
forall a b. (Unbox a, Unbox b) => (a -> b) -> Vector a -> Vector b
U.map c -> (a, b)
f
  {-# INLINE [1] cunzipWith #-}

instance CUnzip PV.Vector where
  cunzip :: Vector (a, b) -> (Vector a, Vector b)
cunzip = Vector (a, b) -> (Vector a, Vector b)
forall (v :: * -> *) a b.
(Vector v a, Vector v b, Vector v (a, b)) =>
v (a, b) -> (v a, v b)
G.unzip
  {-# INLINE [1] cunzip #-}
  cunzipWith :: (c -> (a, b)) -> Vector c -> (Vector a, Vector b)
cunzipWith = \c -> (a, b)
f ->
    (Vector a -> Vector a
forall (v :: * -> *) a (w :: * -> *).
(Vector v a, Vector w a) =>
v a -> w a
G.convert (Vector a -> Vector a)
-> (Vector b -> Vector b)
-> (Vector a, Vector b)
-> (Vector a, Vector b)
forall (a :: * -> * -> *) b c b' c'.
Arrow a =>
a b c -> a b' c' -> a (b, b') (c, c')
*** Vector b -> Vector b
forall (v :: * -> *) a (w :: * -> *).
(Vector v a, Vector w a) =>
v a -> w a
G.convert)  ((Vector a, Vector b) -> (Vector a, Vector b))
-> (Vector c -> (Vector a, Vector b))
-> Vector c
-> (Vector a, Vector b)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (c -> (a, b)) -> Vector c -> (Vector a, Vector b)
forall (f :: * -> *) c a b.
(CUnzip f, Dom f c, Dom f a, Dom f b) =>
(c -> (a, b)) -> f c -> (f a, f b)
cunzipWith @V.Vector c -> (a, b)
f (Vector c -> (Vector a, Vector b))
-> (Vector c -> Vector c) -> Vector c -> (Vector a, Vector b)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Vector c -> Vector c
forall (v :: * -> *) a (w :: * -> *).
(Vector v a, Vector w a) =>
v a -> w a
V.convert
  {-# INLINE [1] cunzipWith #-}

instance CUnzip S.Vector where
  cunzip :: Vector (a, b) -> (Vector a, Vector b)
cunzip = Vector (a, b) -> (Vector a, Vector b)
forall (v :: * -> *) a b.
(Vector v a, Vector v b, Vector v (a, b)) =>
v (a, b) -> (v a, v b)
G.unzip
  {-# INLINE [1] cunzip #-}
  cunzipWith :: (c -> (a, b)) -> Vector c -> (Vector a, Vector b)
cunzipWith = \c -> (a, b)
f ->
    (Vector a -> Vector a
forall (v :: * -> *) a (w :: * -> *).
(Vector v a, Vector w a) =>
v a -> w a
G.convert (Vector a -> Vector a)
-> (Vector b -> Vector b)
-> (Vector a, Vector b)
-> (Vector a, Vector b)
forall (a :: * -> * -> *) b c b' c'.
Arrow a =>
a b c -> a b' c' -> a (b, b') (c, c')
*** Vector b -> Vector b
forall (v :: * -> *) a (w :: * -> *).
(Vector v a, Vector w a) =>
v a -> w a
G.convert)  ((Vector a, Vector b) -> (Vector a, Vector b))
-> (Vector c -> (Vector a, Vector b))
-> Vector c
-> (Vector a, Vector b)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (c -> (a, b)) -> Vector c -> (Vector a, Vector b)
forall (f :: * -> *) c a b.
(CUnzip f, Dom f c, Dom f a, Dom f b) =>
(c -> (a, b)) -> f c -> (f a, f b)
cunzipWith @V.Vector c -> (a, b)
f (Vector c -> (Vector a, Vector b))
-> (Vector c -> Vector c) -> Vector c -> (Vector a, Vector b)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Vector c -> Vector c
forall (v :: * -> *) a (w :: * -> *).
(Vector v a, Vector w a) =>
v a -> w a
V.convert
  {-# INLINE [1] cunzipWith #-}
deriving via WrapFunctor Proxy instance CUnzip Proxy
#if MIN_VERSION_semialign(1,1,0)
deriving via WrapFunctor Seq.Seq instance CUnzip Seq.Seq
deriving via WrapFunctor (M.Map k) instance Ord k => CUnzip (M.Map k)
deriving via WrapFunctor IM.IntMap instance CUnzip IM.IntMap
deriving via WrapFunctor (HM.HashMap k)
  instance (Eq k, Hashable k) => CUnzip (HM.HashMap k)
#endif

instance (CUnzip f, CUnzip g) => CUnzip (SOP.Product f g) where
  cunzipWith :: (c -> (a, b)) -> Product f g c -> (Product f g a, Product f g b)
cunzipWith c -> (a, b)
f (SOP.Pair f c
a g c
b)  =
    (f a -> g a -> Product f g a
forall k (f :: k -> *) (g :: k -> *) (a :: k).
f a -> g a -> Product f g a
SOP.Pair f a
al g a
bl, f b -> g b -> Product f g b
forall k (f :: k -> *) (g :: k -> *) (a :: k).
f a -> g a -> Product f g a
SOP.Pair f b
ar g b
br)
    where
      ~(f a
al, f b
ar) = (c -> (a, b)) -> f c -> (f a, f b)
forall (f :: * -> *) c a b.
(CUnzip f, Dom f c, Dom f a, Dom f b) =>
(c -> (a, b)) -> f c -> (f a, f b)
cunzipWith c -> (a, b)
f f c
a
      ~(g a
bl, g b
br) = (c -> (a, b)) -> g c -> (g a, g b)
forall (f :: * -> *) c a b.
(CUnzip f, Dom f c, Dom f a, Dom f b) =>
(c -> (a, b)) -> f c -> (f a, f b)
cunzipWith c -> (a, b)
f g c
b
  {-# INLINE [1] cunzipWith #-}
  cunzip :: Product f g (a, b) -> (Product f g a, Product f g b)
cunzip (SOP.Pair f (a, b)
a g (a, b)
b)  =
    (f a -> g a -> Product f g a
forall k (f :: k -> *) (g :: k -> *) (a :: k).
f a -> g a -> Product f g a
SOP.Pair f a
al g a
bl, f b -> g b -> Product f g b
forall k (f :: k -> *) (g :: k -> *) (a :: k).
f a -> g a -> Product f g a
SOP.Pair f b
ar g b
br)
    where
      ~(f a
al, f b
ar) = f (a, b) -> (f a, f b)
forall (f :: * -> *) a b.
(CUnzip f, Dom f (a, b), Dom f a, Dom f b) =>
f (a, b) -> (f a, f b)
cunzip f (a, b)
a
      ~(g a
bl, g b
br) = g (a, b) -> (g a, g b)
forall (f :: * -> *) a b.
(CUnzip f, Dom f (a, b), Dom f a, Dom f b) =>
f (a, b) -> (f a, f b)
cunzip g (a, b)
b
  {-# INLINE [1] cunzip #-}

instance (CUnzip f, CUnzip g) => CUnzip (f :*: g) where
  cunzipWith :: (c -> (a, b)) -> (:*:) f g c -> ((:*:) f g a, (:*:) f g b)
cunzipWith c -> (a, b)
f (f c
a :*: g c
b)  =
    (f a
al f a -> g a -> (:*:) f g a
forall k (f :: k -> *) (g :: k -> *) (p :: k).
f p -> g p -> (:*:) f g p
:*: g a
bl, f b
ar f b -> g b -> (:*:) f g b
forall k (f :: k -> *) (g :: k -> *) (p :: k).
f p -> g p -> (:*:) f g p
:*: g b
br)
    where
      ~(f a
al, f b
ar) = (c -> (a, b)) -> f c -> (f a, f b)
forall (f :: * -> *) c a b.
(CUnzip f, Dom f c, Dom f a, Dom f b) =>
(c -> (a, b)) -> f c -> (f a, f b)
cunzipWith c -> (a, b)
f f c
a
      ~(g a
bl, g b
br) = (c -> (a, b)) -> g c -> (g a, g b)
forall (f :: * -> *) c a b.
(CUnzip f, Dom f c, Dom f a, Dom f b) =>
(c -> (a, b)) -> f c -> (f a, f b)
cunzipWith c -> (a, b)
f g c
b
  {-# INLINE [1] cunzipWith #-}
  cunzip :: (:*:) f g (a, b) -> ((:*:) f g a, (:*:) f g b)
cunzip (f (a, b)
a :*: g (a, b)
b)  =
    (f a
al f a -> g a -> (:*:) f g a
forall k (f :: k -> *) (g :: k -> *) (p :: k).
f p -> g p -> (:*:) f g p
:*: g a
bl, f b
ar f b -> g b -> (:*:) f g b
forall k (f :: k -> *) (g :: k -> *) (p :: k).
f p -> g p -> (:*:) f g p
:*: g b
br)
    where
      ~(f a
al, f b
ar) = f (a, b) -> (f a, f b)
forall (f :: * -> *) a b.
(CUnzip f, Dom f (a, b), Dom f a, Dom f b) =>
f (a, b) -> (f a, f b)
cunzip f (a, b)
a
      ~(g a
bl, g b
br) = g (a, b) -> (g a, g b)
forall (f :: * -> *) a b.
(CUnzip f, Dom f (a, b), Dom f a, Dom f b) =>
f (a, b) -> (f a, f b)
cunzip g (a, b)
b
  {-# INLINE [1] cunzip #-}

instance (CUnzip f, CUnzip g) => CUnzip (Compose f g) where
  cunzipWith :: (c -> (a, b)) -> Compose f g c -> (Compose f g a, Compose f g b)
cunzipWith c -> (a, b)
f (Compose f (g c)
a) = (f (g a) -> Compose f g a
forall k k1 (f :: k -> *) (g :: k1 -> k) (a :: k1).
f (g a) -> Compose f g a
Compose f (g a)
y, f (g b) -> Compose f g b
forall k k1 (f :: k -> *) (g :: k1 -> k) (a :: k1).
f (g a) -> Compose f g a
Compose f (g b)
z) where
    ~(f (g a)
y, f (g b)
z) = (g c -> (g a, g b)) -> f (g c) -> (f (g a), f (g b))
forall (f :: * -> *) c a b.
(CUnzip f, Dom f c, Dom f a, Dom f b) =>
(c -> (a, b)) -> f c -> (f a, f b)
cunzipWith ((c -> (a, b)) -> g c -> (g a, g b)
forall (f :: * -> *) c a b.
(CUnzip f, Dom f c, Dom f a, Dom f b) =>
(c -> (a, b)) -> f c -> (f a, f b)
cunzipWith c -> (a, b)
f) f (g c)
a
  {-# INLINE [1] cunzipWith #-}

instance (CUnzip f, CUnzip g) => CUnzip (f :.: g) where
  cunzipWith :: (c -> (a, b)) -> (:.:) f g c -> ((:.:) f g a, (:.:) f g b)
cunzipWith c -> (a, b)
f (Comp1 f (g c)
a) = (f (g a) -> (:.:) f g a
forall k2 k1 (f :: k2 -> *) (g :: k1 -> k2) (p :: k1).
f (g p) -> (:.:) f g p
Comp1 f (g a)
y, f (g b) -> (:.:) f g b
forall k2 k1 (f :: k2 -> *) (g :: k1 -> k2) (p :: k1).
f (g p) -> (:.:) f g p
Comp1 f (g b)
z) where
    ~(f (g a)
y, f (g b)
z) = (g c -> (g a, g b)) -> f (g c) -> (f (g a), f (g b))
forall (f :: * -> *) c a b.
(CUnzip f, Dom f c, Dom f a, Dom f b) =>
(c -> (a, b)) -> f c -> (f a, f b)
cunzipWith ((c -> (a, b)) -> g c -> (g a, g b)
forall (f :: * -> *) c a b.
(CUnzip f, Dom f c, Dom f a, Dom f b) =>
(c -> (a, b)) -> f c -> (f a, f b)
cunzipWith c -> (a, b)
f) f (g c)
a
  {-# INLINE [1] cunzipWith #-}

instance (MT.IsSequence mono, MonoZip mono)
  => CZip (WrapMono mono) where
    czipWith :: (a -> b -> c)
-> WrapMono mono a -> WrapMono mono b -> WrapMono mono c
czipWith a -> b -> c
f = (mono -> mono -> mono)
-> WrapMono mono a -> WrapMono mono b -> WrapMono mono c
coerce ((mono -> mono -> mono)
 -> WrapMono mono a -> WrapMono mono b -> WrapMono mono c)
-> (mono -> mono -> mono)
-> WrapMono mono a
-> WrapMono mono b
-> WrapMono mono c
forall a b. (a -> b) -> a -> b
$ (Element mono -> Element mono -> Element mono)
-> mono -> mono -> mono
forall mono.
MonoZip mono =>
(Element mono -> Element mono -> Element mono)
-> mono -> mono -> mono
ozipWith @mono a -> b -> c
Element mono -> Element mono -> Element mono
f
    {-# INLINE [1] czipWith #-}

instance (MT.IsSequence mono, MonoZip mono)
  => CUnzip (WrapMono mono) where
    cunzipWith :: (c -> (a, b))
-> WrapMono mono c -> (WrapMono mono a, WrapMono mono b)
cunzipWith c -> (a, b)
f = (mono -> (mono, mono))
-> WrapMono mono c -> (WrapMono mono a, WrapMono mono b)
coerce ((mono -> (mono, mono))
 -> WrapMono mono c -> (WrapMono mono a, WrapMono mono b))
-> (mono -> (mono, mono))
-> WrapMono mono c
-> (WrapMono mono a, WrapMono mono b)
forall a b. (a -> b) -> a -> b
$ (Element mono -> Element mono) -> mono -> mono
forall mono.
MonoFunctor mono =>
(Element mono -> Element mono) -> mono -> mono
omap @mono ((a, b) -> a
forall a b. (a, b) -> a
fst ((a, b) -> a) -> (c -> (a, b)) -> c -> a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. c -> (a, b)
f) (mono -> mono) -> (mono -> mono) -> mono -> (mono, mono)
forall (a :: * -> * -> *) b c c'.
Arrow a =>
a b c -> a b c' -> a b (c, c')
&&& (Element mono -> Element mono) -> mono -> mono
forall mono.
MonoFunctor mono =>
(Element mono -> Element mono) -> mono -> mono
omap @mono ((a, b) -> b
forall a b. (a, b) -> b
snd ((a, b) -> b) -> (c -> (a, b)) -> c -> b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. c -> (a, b)
f)