-- |
-- Module      : Foundation.Collection.Zippable
-- License     : BSD-style
-- Maintainer  : foundation
-- Stability   : experimental
-- Portability : portable
--
-- Common functions (e. g. 'zip', 'zipWith') that are useful for combining
-- multiple collections.
--
{-# LANGUAGE FlexibleInstances     #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE StandaloneDeriving    #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
module Foundation.Collection.Zippable
    ( BoxedZippable(..)
    , Zippable(..)
    ) where

import qualified Basement.UArray as UV
import qualified Basement.BoxedArray as BA
import qualified Basement.String as S
import           Foundation.Collection.Element
import           Foundation.Collection.Sequential
import           Basement.Compat.Base
import           Basement.Types.AsciiString(AsciiString(..))
import qualified Prelude
import           GHC.ST

class Sequential col => Zippable col where

  -- | 'zipWith' generalises 'zip' by zipping with the function given as the
  --   first argument, instead of a tupling function. For example, @'zipWith' (+)@
  --   is applied to two collections to produce the collection of corresponding
  --   sums.
  zipWith :: (Sequential a, Sequential b)
          => (Element a -> Element b -> Element col)
          -> a -> b -> col
  zipWith f :: Element a -> Element b -> Element col
f a :: a
a b :: b
b = (Element [Element a] -> Element [Element b] -> Element col)
-> ([Element a], [Element b]) -> col
forall c a b.
(Sequential c, Sequential a, Sequential b) =>
(Element a -> Element b -> Element c) -> (a, b) -> c
go Element a -> Element b -> Element col
Element [Element a] -> Element [Element b] -> Element col
f (a -> [Item a]
forall l. IsList l => l -> [Item l]
toList a
a, b -> [Item b]
forall l. IsList l => l -> [Item l]
toList b
b)
    where go :: (Element a -> Element b -> Element c) -> (a, b) -> c
go f' :: Element a -> Element b -> Element c
f' = c
-> (((Element a, Element b), (a, b)) -> c)
-> Maybe ((Element a, Element b), (a, b))
-> c
forall b a. b -> (a -> b) -> Maybe a -> b
maybe c
forall a. Monoid a => a
mempty (\(x :: (Element a, Element b)
x, xs :: (a, b)
xs) -> (Element a -> Element b -> Element c)
-> (Element a, Element b) -> Element c
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry2 Element a -> Element b -> Element c
f' (Element a, Element b)
x Element c -> c -> c
forall c. Sequential c => Element c -> c -> c
`cons` (Element a -> Element b -> Element c) -> (a, b) -> c
go Element a -> Element b -> Element c
f' (a, b)
xs) (Maybe ((Element a, Element b), (a, b)) -> c)
-> ((a, b) -> Maybe ((Element a, Element b), (a, b)))
-> (a, b)
-> c
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. (a, b) -> Maybe ((Element a, Element b), (a, b))
forall a b.
(Sequential a, Sequential b) =>
(a, b) -> Maybe ((Element a, Element b), (a, b))
uncons2

  -- | Like 'zipWith', but works with 3 collections.
  zipWith3 :: (Sequential a, Sequential b, Sequential c)
           => (Element a -> Element b -> Element c -> Element col)
           -> a -> b -> c -> col
  zipWith3 f :: Element a -> Element b -> Element c -> Element col
f a :: a
a b :: b
b c :: c
c = (Element [Element a]
 -> Element [Element b] -> Element [Element c] -> Element col)
-> ([Element a], [Element b], [Element c]) -> col
forall c a b c.
(Sequential c, Sequential a, Sequential b, Sequential c) =>
(Element a -> Element b -> Element c -> Element c)
-> (a, b, c) -> c
go Element a -> Element b -> Element c -> Element col
Element [Element a]
-> Element [Element b] -> Element [Element c] -> Element col
f (a -> [Item a]
forall l. IsList l => l -> [Item l]
toList a
a, b -> [Item b]
forall l. IsList l => l -> [Item l]
toList b
b, c -> [Item c]
forall l. IsList l => l -> [Item l]
toList c
c)
    where go :: (Element a -> Element b -> Element c -> Element c)
-> (a, b, c) -> c
go f' :: Element a -> Element b -> Element c -> Element c
f' = c
-> (((Element a, Element b, Element c), (a, b, c)) -> c)
-> Maybe ((Element a, Element b, Element c), (a, b, c))
-> c
forall b a. b -> (a -> b) -> Maybe a -> b
maybe c
forall a. Monoid a => a
mempty (\(x :: (Element a, Element b, Element c)
x, xs :: (a, b, c)
xs) -> (Element a -> Element b -> Element c -> Element c)
-> (Element a, Element b, Element c) -> Element c
forall a b c d. (a -> b -> c -> d) -> (a, b, c) -> d
uncurry3 Element a -> Element b -> Element c -> Element c
f' (Element a, Element b, Element c)
x Element c -> c -> c
forall c. Sequential c => Element c -> c -> c
`cons` (Element a -> Element b -> Element c -> Element c)
-> (a, b, c) -> c
go Element a -> Element b -> Element c -> Element c
f' (a, b, c)
xs) (Maybe ((Element a, Element b, Element c), (a, b, c)) -> c)
-> ((a, b, c)
    -> Maybe ((Element a, Element b, Element c), (a, b, c)))
-> (a, b, c)
-> c
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. (a, b, c) -> Maybe ((Element a, Element b, Element c), (a, b, c))
forall a b c.
(Sequential a, Sequential b, Sequential c) =>
(a, b, c) -> Maybe ((Element a, Element b, Element c), (a, b, c))
uncons3

  -- | Like 'zipWith', but works with 4 collections.
  zipWith4 :: (Sequential a, Sequential b, Sequential c, Sequential d)
           => (Element a -> Element b -> Element c -> Element d -> Element col)
           -> a -> b -> c -> d -> col
  zipWith4 fn :: Element a -> Element b -> Element c -> Element d -> Element col
fn a :: a
a b :: b
b c :: c
c d :: d
d = (Element [Element a]
 -> Element [Element b]
 -> Element [Element c]
 -> Element [Element d]
 -> Element col)
-> ([Element a], [Element b], [Element c], [Element d]) -> col
forall c a b c d.
(Sequential c, Sequential a, Sequential b, Sequential c,
 Sequential d) =>
(Element a -> Element b -> Element c -> Element d -> Element c)
-> (a, b, c, d) -> c
go Element a -> Element b -> Element c -> Element d -> Element col
Element [Element a]
-> Element [Element b]
-> Element [Element c]
-> Element [Element d]
-> Element col
fn (a -> [Item a]
forall l. IsList l => l -> [Item l]
toList a
a, b -> [Item b]
forall l. IsList l => l -> [Item l]
toList b
b, c -> [Item c]
forall l. IsList l => l -> [Item l]
toList c
c, d -> [Item d]
forall l. IsList l => l -> [Item l]
toList d
d)
    where go :: (Element a -> Element b -> Element c -> Element d -> Element c)
-> (a, b, c, d) -> c
go f' :: Element a -> Element b -> Element c -> Element d -> Element c
f' = c
-> (((Element a, Element b, Element c, Element d), (a, b, c, d))
    -> c)
-> Maybe
     ((Element a, Element b, Element c, Element d), (a, b, c, d))
-> c
forall b a. b -> (a -> b) -> Maybe a -> b
maybe c
forall a. Monoid a => a
mempty (\(x :: (Element a, Element b, Element c, Element d)
x, xs :: (a, b, c, d)
xs) -> (Element a -> Element b -> Element c -> Element d -> Element c)
-> (Element a, Element b, Element c, Element d) -> Element c
forall a b c d g. (a -> b -> c -> d -> g) -> (a, b, c, d) -> g
uncurry4 Element a -> Element b -> Element c -> Element d -> Element c
f' (Element a, Element b, Element c, Element d)
x Element c -> c -> c
forall c. Sequential c => Element c -> c -> c
`cons` (Element a -> Element b -> Element c -> Element d -> Element c)
-> (a, b, c, d) -> c
go Element a -> Element b -> Element c -> Element d -> Element c
f' (a, b, c, d)
xs) (Maybe ((Element a, Element b, Element c, Element d), (a, b, c, d))
 -> c)
-> ((a, b, c, d)
    -> Maybe
         ((Element a, Element b, Element c, Element d), (a, b, c, d)))
-> (a, b, c, d)
-> c
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. (a, b, c, d)
-> Maybe
     ((Element a, Element b, Element c, Element d), (a, b, c, d))
forall a b c d.
(Sequential a, Sequential b, Sequential c, Sequential d) =>
(a, b, c, d)
-> Maybe
     ((Element a, Element b, Element c, Element d), (a, b, c, d))
uncons4

  -- | Like 'zipWith', but works with 5 collections.
  zipWith5 :: (Sequential a, Sequential b, Sequential c, Sequential d, Sequential e)
           => (Element a -> Element b -> Element c -> Element d -> Element e -> Element col)
           -> a -> b -> c -> d -> e -> col
  zipWith5 fn :: Element a
-> Element b -> Element c -> Element d -> Element e -> Element col
fn a :: a
a b :: b
b c :: c
c d :: d
d e :: e
e = (Element [Element a]
 -> Element [Element b]
 -> Element [Element c]
 -> Element [Element d]
 -> Element [Element e]
 -> Element col)
-> ([Element a], [Element b], [Element c], [Element d],
    [Element e])
-> col
forall c a b c d e.
(Sequential c, Sequential a, Sequential b, Sequential c,
 Sequential d, Sequential e) =>
(Element a
 -> Element b -> Element c -> Element d -> Element e -> Element c)
-> (a, b, c, d, e) -> c
go Element a
-> Element b -> Element c -> Element d -> Element e -> Element col
Element [Element a]
-> Element [Element b]
-> Element [Element c]
-> Element [Element d]
-> Element [Element e]
-> Element col
fn (a -> [Item a]
forall l. IsList l => l -> [Item l]
toList a
a, b -> [Item b]
forall l. IsList l => l -> [Item l]
toList b
b, c -> [Item c]
forall l. IsList l => l -> [Item l]
toList c
c, d -> [Item d]
forall l. IsList l => l -> [Item l]
toList d
d, e -> [Item e]
forall l. IsList l => l -> [Item l]
toList e
e)
    where go :: (Element a
 -> Element b -> Element c -> Element d -> Element e -> Element c)
-> (a, b, c, d, e) -> c
go f' :: Element a
-> Element b -> Element c -> Element d -> Element e -> Element c
f' = c
-> (((Element a, Element b, Element c, Element d, Element e),
     (a, b, c, d, e))
    -> c)
-> Maybe
     ((Element a, Element b, Element c, Element d, Element e),
      (a, b, c, d, e))
-> c
forall b a. b -> (a -> b) -> Maybe a -> b
maybe c
forall a. Monoid a => a
mempty (\(x :: (Element a, Element b, Element c, Element d, Element e)
x, xs :: (a, b, c, d, e)
xs) -> (Element a
 -> Element b -> Element c -> Element d -> Element e -> Element c)
-> (Element a, Element b, Element c, Element d, Element e)
-> Element c
forall a b c d e f.
(a -> b -> c -> d -> e -> f) -> (a, b, c, d, e) -> f
uncurry5 Element a
-> Element b -> Element c -> Element d -> Element e -> Element c
f' (Element a, Element b, Element c, Element d, Element e)
x Element c -> c -> c
forall c. Sequential c => Element c -> c -> c
`cons` (Element a
 -> Element b -> Element c -> Element d -> Element e -> Element c)
-> (a, b, c, d, e) -> c
go Element a
-> Element b -> Element c -> Element d -> Element e -> Element c
f' (a, b, c, d, e)
xs) (Maybe
   ((Element a, Element b, Element c, Element d, Element e),
    (a, b, c, d, e))
 -> c)
-> ((a, b, c, d, e)
    -> Maybe
         ((Element a, Element b, Element c, Element d, Element e),
          (a, b, c, d, e)))
-> (a, b, c, d, e)
-> c
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. (a, b, c, d, e)
-> Maybe
     ((Element a, Element b, Element c, Element d, Element e),
      (a, b, c, d, e))
forall a b c d e.
(Sequential a, Sequential b, Sequential c, Sequential d,
 Sequential e) =>
(a, b, c, d, e)
-> Maybe
     ((Element a, Element b, Element c, Element d, Element e),
      (a, b, c, d, e))
uncons5

  -- | Like 'zipWith', but works with 6 collections.
  zipWith6 :: ( Sequential a, Sequential b, Sequential c, Sequential d, Sequential e
              , Sequential f)
           => (Element a -> Element b -> Element c -> Element d -> Element e -> Element f -> Element col)
           -> a -> b -> c -> d -> e -> f -> col
  zipWith6 fn :: Element a
-> Element b
-> Element c
-> Element d
-> Element e
-> Element f
-> Element col
fn a :: a
a b :: b
b c :: c
c d :: d
d e :: e
e f :: f
f = (Element [Element a]
 -> Element [Element b]
 -> Element [Element c]
 -> Element [Element d]
 -> Element [Element e]
 -> Element [Element f]
 -> Element col)
-> ([Element a], [Element b], [Element c], [Element d],
    [Element e], [Element f])
-> col
forall c a b c d e f.
(Sequential c, Sequential a, Sequential b, Sequential c,
 Sequential d, Sequential e, Sequential f) =>
(Element a
 -> Element b
 -> Element c
 -> Element d
 -> Element e
 -> Element f
 -> Element c)
-> (a, b, c, d, e, f) -> c
go Element a
-> Element b
-> Element c
-> Element d
-> Element e
-> Element f
-> Element col
Element [Element a]
-> Element [Element b]
-> Element [Element c]
-> Element [Element d]
-> Element [Element e]
-> Element [Element f]
-> Element col
fn (a -> [Item a]
forall l. IsList l => l -> [Item l]
toList a
a, b -> [Item b]
forall l. IsList l => l -> [Item l]
toList b
b, c -> [Item c]
forall l. IsList l => l -> [Item l]
toList c
c, d -> [Item d]
forall l. IsList l => l -> [Item l]
toList d
d, e -> [Item e]
forall l. IsList l => l -> [Item l]
toList e
e, f -> [Item f]
forall l. IsList l => l -> [Item l]
toList f
f)
    where go :: (Element a
 -> Element b
 -> Element c
 -> Element d
 -> Element e
 -> Element f
 -> Element c)
-> (a, b, c, d, e, f) -> c
go f' :: Element a
-> Element b
-> Element c
-> Element d
-> Element e
-> Element f
-> Element c
f' = c
-> (((Element a, Element b, Element c, Element d, Element e,
      Element f),
     (a, b, c, d, e, f))
    -> c)
-> Maybe
     ((Element a, Element b, Element c, Element d, Element e,
       Element f),
      (a, b, c, d, e, f))
-> c
forall b a. b -> (a -> b) -> Maybe a -> b
maybe c
forall a. Monoid a => a
mempty (\(x :: (Element a, Element b, Element c, Element d, Element e, Element f)
x, xs :: (a, b, c, d, e, f)
xs) -> (Element a
 -> Element b
 -> Element c
 -> Element d
 -> Element e
 -> Element f
 -> Element c)
-> (Element a, Element b, Element c, Element d, Element e,
    Element f)
-> Element c
forall a b c d e f g.
(a -> b -> c -> d -> e -> f -> g) -> (a, b, c, d, e, f) -> g
uncurry6 Element a
-> Element b
-> Element c
-> Element d
-> Element e
-> Element f
-> Element c
f' (Element a, Element b, Element c, Element d, Element e, Element f)
x Element c -> c -> c
forall c. Sequential c => Element c -> c -> c
`cons` (Element a
 -> Element b
 -> Element c
 -> Element d
 -> Element e
 -> Element f
 -> Element c)
-> (a, b, c, d, e, f) -> c
go Element a
-> Element b
-> Element c
-> Element d
-> Element e
-> Element f
-> Element c
f' (a, b, c, d, e, f)
xs) (Maybe
   ((Element a, Element b, Element c, Element d, Element e,
     Element f),
    (a, b, c, d, e, f))
 -> c)
-> ((a, b, c, d, e, f)
    -> Maybe
         ((Element a, Element b, Element c, Element d, Element e,
           Element f),
          (a, b, c, d, e, f)))
-> (a, b, c, d, e, f)
-> c
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. (a, b, c, d, e, f)
-> Maybe
     ((Element a, Element b, Element c, Element d, Element e,
       Element f),
      (a, b, c, d, e, f))
forall a b c d e f.
(Sequential a, Sequential b, Sequential c, Sequential d,
 Sequential e, Sequential f) =>
(a, b, c, d, e, f)
-> Maybe
     ((Element a, Element b, Element c, Element d, Element e,
       Element f),
      (a, b, c, d, e, f))
uncons6

  -- | Like 'zipWith', but works with 7 collections.
  zipWith7 :: ( Sequential a, Sequential b, Sequential c, Sequential d, Sequential e
              , Sequential f, Sequential g )
           => (Element a -> Element b -> Element c -> Element d -> Element e -> Element f -> Element g -> Element col)
           -> a -> b -> c -> d -> e -> f -> g -> col
  zipWith7 fn :: Element a
-> Element b
-> Element c
-> Element d
-> Element e
-> Element f
-> Element g
-> Element col
fn a :: a
a b :: b
b c :: c
c d :: d
d e :: e
e f :: f
f g :: g
g = (Element [Element a]
 -> Element [Element b]
 -> Element [Element c]
 -> Element [Element d]
 -> Element [Element e]
 -> Element [Element f]
 -> Element [Element g]
 -> Element col)
-> ([Element a], [Element b], [Element c], [Element d],
    [Element e], [Element f], [Element g])
-> col
forall c a b c d e f g.
(Sequential c, Sequential a, Sequential b, Sequential c,
 Sequential d, Sequential e, Sequential f, Sequential g) =>
(Element a
 -> Element b
 -> Element c
 -> Element d
 -> Element e
 -> Element f
 -> Element g
 -> Element c)
-> (a, b, c, d, e, f, g) -> c
go Element a
-> Element b
-> Element c
-> Element d
-> Element e
-> Element f
-> Element g
-> Element col
Element [Element a]
-> Element [Element b]
-> Element [Element c]
-> Element [Element d]
-> Element [Element e]
-> Element [Element f]
-> Element [Element g]
-> Element col
fn (a -> [Item a]
forall l. IsList l => l -> [Item l]
toList a
a, b -> [Item b]
forall l. IsList l => l -> [Item l]
toList b
b, c -> [Item c]
forall l. IsList l => l -> [Item l]
toList c
c, d -> [Item d]
forall l. IsList l => l -> [Item l]
toList d
d, e -> [Item e]
forall l. IsList l => l -> [Item l]
toList e
e, f -> [Item f]
forall l. IsList l => l -> [Item l]
toList f
f, g -> [Item g]
forall l. IsList l => l -> [Item l]
toList g
g)
    where go :: (Element a
 -> Element b
 -> Element c
 -> Element d
 -> Element e
 -> Element f
 -> Element g
 -> Element c)
-> (a, b, c, d, e, f, g) -> c
go f' :: Element a
-> Element b
-> Element c
-> Element d
-> Element e
-> Element f
-> Element g
-> Element c
f' = c
-> (((Element a, Element b, Element c, Element d, Element e,
      Element f, Element g),
     (a, b, c, d, e, f, g))
    -> c)
-> Maybe
     ((Element a, Element b, Element c, Element d, Element e, Element f,
       Element g),
      (a, b, c, d, e, f, g))
-> c
forall b a. b -> (a -> b) -> Maybe a -> b
maybe c
forall a. Monoid a => a
mempty (\(x :: (Element a, Element b, Element c, Element d, Element e, Element f,
 Element g)
x, xs :: (a, b, c, d, e, f, g)
xs) -> (Element a
 -> Element b
 -> Element c
 -> Element d
 -> Element e
 -> Element f
 -> Element g
 -> Element c)
-> (Element a, Element b, Element c, Element d, Element e,
    Element f, Element g)
-> Element c
forall a b c d e f g h.
(a -> b -> c -> d -> e -> f -> g -> h)
-> (a, b, c, d, e, f, g) -> h
uncurry7 Element a
-> Element b
-> Element c
-> Element d
-> Element e
-> Element f
-> Element g
-> Element c
f' (Element a, Element b, Element c, Element d, Element e, Element f,
 Element g)
x Element c -> c -> c
forall c. Sequential c => Element c -> c -> c
`cons` (Element a
 -> Element b
 -> Element c
 -> Element d
 -> Element e
 -> Element f
 -> Element g
 -> Element c)
-> (a, b, c, d, e, f, g) -> c
go Element a
-> Element b
-> Element c
-> Element d
-> Element e
-> Element f
-> Element g
-> Element c
f' (a, b, c, d, e, f, g)
xs) (Maybe
   ((Element a, Element b, Element c, Element d, Element e, Element f,
     Element g),
    (a, b, c, d, e, f, g))
 -> c)
-> ((a, b, c, d, e, f, g)
    -> Maybe
         ((Element a, Element b, Element c, Element d, Element e, Element f,
           Element g),
          (a, b, c, d, e, f, g)))
-> (a, b, c, d, e, f, g)
-> c
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. (a, b, c, d, e, f, g)
-> Maybe
     ((Element a, Element b, Element c, Element d, Element e, Element f,
       Element g),
      (a, b, c, d, e, f, g))
forall a b c d e f g.
(Sequential a, Sequential b, Sequential c, Sequential d,
 Sequential e, Sequential f, Sequential g) =>
(a, b, c, d, e, f, g)
-> Maybe
     ((Element a, Element b, Element c, Element d, Element e, Element f,
       Element g),
      (a, b, c, d, e, f, g))
uncons7

instance Zippable [c]

instance UV.PrimType ty => Zippable (UV.UArray ty) where
  zipWith :: (Element a -> Element b -> Element (UArray ty))
-> a -> b -> UArray ty
zipWith f :: Element a -> Element b -> Element (UArray ty)
f as :: a
as bs :: b
bs = (forall s. ST s (UArray ty)) -> UArray ty
forall a. (forall s. ST s a) -> a
runST ((forall s. ST s (UArray ty)) -> UArray ty)
-> (forall s. ST s (UArray ty)) -> UArray ty
forall a b. (a -> b) -> a -> b
$ Int
-> Builder (UArray ty) (MUArray ty) ty (ST s) () ()
-> ST s (UArray ty)
forall ty (m :: * -> *).
(PrimType ty, PrimMonad m) =>
Int -> Builder (UArray ty) (MUArray ty) ty m () () -> m (UArray ty)
UV.builderBuild_ 64 (Builder (UArray ty) (MUArray ty) ty (ST s) () ()
 -> ST s (UArray ty))
-> Builder (UArray ty) (MUArray ty) ty (ST s) () ()
-> ST s (UArray ty)
forall a b. (a -> b) -> a -> b
$ (Element a -> Element b -> ty)
-> [Element a]
-> [Element b]
-> Builder (UArray ty) (MUArray ty) ty (ST s) () ()
forall (state :: * -> *) ty t t err.
(PrimType ty, PrimMonad state) =>
(t -> t -> ty)
-> [t] -> [t] -> Builder (UArray ty) (MUArray ty) ty state err ()
go Element a -> Element b -> ty
Element a -> Element b -> Element (UArray ty)
f (a -> [Item a]
forall l. IsList l => l -> [Item l]
toList a
as) (b -> [Item b]
forall l. IsList l => l -> [Item l]
toList b
bs)
    where
      go :: (t -> t -> ty)
-> [t] -> [t] -> Builder (UArray ty) (MUArray ty) ty state err ()
go _  []       _        = () -> Builder (UArray ty) (MUArray ty) ty state err ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
      go _  _        []       = () -> Builder (UArray ty) (MUArray ty) ty state err ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
      go f' :: t -> t -> ty
f' (a' :: t
a':as' :: [t]
as') (b' :: t
b':bs' :: [t]
bs') = ty -> Builder (UArray ty) (MUArray ty) ty state err ()
forall ty (state :: * -> *) err.
(PrimType ty, PrimMonad state) =>
ty -> Builder (UArray ty) (MUArray ty) ty state err ()
UV.builderAppend (t -> t -> ty
f' t
a' t
b') Builder (UArray ty) (MUArray ty) ty state err ()
-> Builder (UArray ty) (MUArray ty) ty state err ()
-> Builder (UArray ty) (MUArray ty) ty state err ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> (t -> t -> ty)
-> [t] -> [t] -> Builder (UArray ty) (MUArray ty) ty state err ()
go t -> t -> ty
f' [t]
as' [t]
bs'

instance Zippable (BA.Array ty) where
  zipWith :: (Element a -> Element b -> Element (Array ty))
-> a -> b -> Array ty
zipWith f :: Element a -> Element b -> Element (Array ty)
f as :: a
as bs :: b
bs = (forall s. ST s (Array ty)) -> Array ty
forall a. (forall s. ST s a) -> a
runST ((forall s. ST s (Array ty)) -> Array ty)
-> (forall s. ST s (Array ty)) -> Array ty
forall a b. (a -> b) -> a -> b
$ Int
-> Builder (Array ty) (MArray ty) ty (ST s) () ()
-> ST s (Array ty)
forall (m :: * -> *) ty.
PrimMonad m =>
Int -> Builder (Array ty) (MArray ty) ty m () () -> m (Array ty)
BA.builderBuild_ 64 (Builder (Array ty) (MArray ty) ty (ST s) () () -> ST s (Array ty))
-> Builder (Array ty) (MArray ty) ty (ST s) () ()
-> ST s (Array ty)
forall a b. (a -> b) -> a -> b
$ (Element a -> Element b -> ty)
-> [Element a]
-> [Element b]
-> Builder (Array ty) (MArray ty) ty (ST s) () ()
forall (state :: * -> *) t t ty err.
PrimMonad state =>
(t -> t -> ty)
-> [t] -> [t] -> Builder (Array ty) (MArray ty) ty state err ()
go Element a -> Element b -> ty
Element a -> Element b -> Element (Array ty)
f (a -> [Item a]
forall l. IsList l => l -> [Item l]
toList a
as) (b -> [Item b]
forall l. IsList l => l -> [Item l]
toList b
bs)
    where
      go :: (t -> t -> ty)
-> [t] -> [t] -> Builder (Array ty) (MArray ty) ty state err ()
go _  []       _        = () -> Builder (Array ty) (MArray ty) ty state err ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
      go _  _        []       = () -> Builder (Array ty) (MArray ty) ty state err ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
      go f' :: t -> t -> ty
f' (a' :: t
a':as' :: [t]
as') (b' :: t
b':bs' :: [t]
bs') = ty -> Builder (Array ty) (MArray ty) ty state err ()
forall (state :: * -> *) ty err.
PrimMonad state =>
ty -> Builder (Array ty) (MArray ty) ty state err ()
BA.builderAppend (t -> t -> ty
f' t
a' t
b') Builder (Array ty) (MArray ty) ty state err ()
-> Builder (Array ty) (MArray ty) ty state err ()
-> Builder (Array ty) (MArray ty) ty state err ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> (t -> t -> ty)
-> [t] -> [t] -> Builder (Array ty) (MArray ty) ty state err ()
go t -> t -> ty
f' [t]
as' [t]
bs'

instance Zippable S.String where
  zipWith :: (Element a -> Element b -> Element String) -> a -> b -> String
zipWith f :: Element a -> Element b -> Element String
f as :: a
as bs :: b
bs = (forall s. ST s String) -> String
forall a. (forall s. ST s a) -> a
runST ((forall s. ST s String) -> String)
-> (forall s. ST s String) -> String
forall a b. (a -> b) -> a -> b
$ Int
-> Builder String MutableString Word8 (ST s) () () -> ST s String
forall (m :: * -> *).
PrimMonad m =>
Int -> Builder String MutableString Word8 m () () -> m String
S.builderBuild_ 64 (Builder String MutableString Word8 (ST s) () () -> ST s String)
-> Builder String MutableString Word8 (ST s) () () -> ST s String
forall a b. (a -> b) -> a -> b
$ (Element a -> Element b -> Char)
-> [Element a]
-> [Element b]
-> Builder String MutableString Word8 (ST s) () ()
forall (state :: * -> *) t t err.
PrimMonad state =>
(t -> t -> Char)
-> [t] -> [t] -> Builder String MutableString Word8 state err ()
go Element a -> Element b -> Char
Element a -> Element b -> Element String
f (a -> [Item a]
forall l. IsList l => l -> [Item l]
toList a
as) (b -> [Item b]
forall l. IsList l => l -> [Item l]
toList b
bs)
    where
      go :: (t -> t -> Char)
-> [t] -> [t] -> Builder String MutableString Word8 state err ()
go _  []       _        = () -> Builder String MutableString Word8 state err ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
      go _  _        []       = () -> Builder String MutableString Word8 state err ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
      go f' :: t -> t -> Char
f' (a' :: t
a':as' :: [t]
as') (b' :: t
b':bs' :: [t]
bs') = Char -> Builder String MutableString Word8 state err ()
forall (state :: * -> *) err.
PrimMonad state =>
Char -> Builder String MutableString Word8 state err ()
S.builderAppend (t -> t -> Char
f' t
a' t
b') Builder String MutableString Word8 state err ()
-> Builder String MutableString Word8 state err ()
-> Builder String MutableString Word8 state err ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> (t -> t -> Char)
-> [t] -> [t] -> Builder String MutableString Word8 state err ()
go t -> t -> Char
f' [t]
as' [t]
bs'

deriving instance Zippable AsciiString

class Zippable col => BoxedZippable col where

  -- | 'zip' takes two collections and returns a collections of corresponding
  --   pairs. If one input collection is short, excess elements of the longer
  --   collection are discarded.
  zip :: ( Sequential a, Sequential b
         , Element col ~ (Element a, Element b) )
      => a -> b -> col
  zip = (Element a -> Element b -> Element col) -> a -> b -> col
forall col a b.
(Zippable col, Sequential a, Sequential b) =>
(Element a -> Element b -> Element col) -> a -> b -> col
zipWith (,)

  -- | Like 'zip', but works with 3 collections.
  zip3 :: ( Sequential a, Sequential b, Sequential c
          , Element col ~ (Element a, Element b, Element c) )
       => a -> b -> c -> col
  zip3 = (Element a -> Element b -> Element c -> Element col)
-> a -> b -> c -> col
forall col a b c.
(Zippable col, Sequential a, Sequential b, Sequential c) =>
(Element a -> Element b -> Element c -> Element col)
-> a -> b -> c -> col
zipWith3 (,,)

  -- | Like 'zip', but works with 4 collections.
  zip4 :: ( Sequential a, Sequential b, Sequential c, Sequential d
          , Element col ~ (Element a, Element b, Element c, Element d) )
       => a -> b -> c -> d -> col
  zip4 = (Element a -> Element b -> Element c -> Element d -> Element col)
-> a -> b -> c -> d -> col
forall col a b c d.
(Zippable col, Sequential a, Sequential b, Sequential c,
 Sequential d) =>
(Element a -> Element b -> Element c -> Element d -> Element col)
-> a -> b -> c -> d -> col
zipWith4 (,,,)

  -- | Like 'zip', but works with 5 collections.
  zip5 :: ( Sequential a, Sequential b, Sequential c, Sequential d, Sequential e
          , Element col ~ (Element a, Element b, Element c, Element d, Element e) )
       => a -> b -> c -> d -> e -> col
  zip5 = (Element a
 -> Element b -> Element c -> Element d -> Element e -> Element col)
-> a -> b -> c -> d -> e -> col
forall col a b c d e.
(Zippable col, Sequential a, Sequential b, Sequential c,
 Sequential d, Sequential e) =>
(Element a
 -> Element b -> Element c -> Element d -> Element e -> Element col)
-> a -> b -> c -> d -> e -> col
zipWith5 (,,,,)

  -- | Like 'zip', but works with 6 collections.
  zip6 :: ( Sequential a, Sequential b, Sequential c, Sequential d, Sequential e, Sequential f
          , Element col ~ (Element a, Element b, Element c, Element d, Element e, Element f) )
       => a -> b -> c -> d -> e -> f -> col
  zip6 = (Element a
 -> Element b
 -> Element c
 -> Element d
 -> Element e
 -> Element f
 -> Element col)
-> a -> b -> c -> d -> e -> f -> col
forall col a b c d e f.
(Zippable col, Sequential a, Sequential b, Sequential c,
 Sequential d, Sequential e, Sequential f) =>
(Element a
 -> Element b
 -> Element c
 -> Element d
 -> Element e
 -> Element f
 -> Element col)
-> a -> b -> c -> d -> e -> f -> col
zipWith6 (,,,,,)

  -- | Like 'zip', but works with 7 collections.
  zip7 :: ( Sequential a, Sequential b, Sequential c, Sequential d, Sequential e, Sequential f, Sequential g
          , Element col ~ (Element a, Element b, Element c, Element d, Element e, Element f, Element g) )
       => a -> b -> c -> d -> e -> f -> g -> col
  zip7 = (Element a
 -> Element b
 -> Element c
 -> Element d
 -> Element e
 -> Element f
 -> Element g
 -> Element col)
-> a -> b -> c -> d -> e -> f -> g -> col
forall col a b c d e f g.
(Zippable col, Sequential a, Sequential b, Sequential c,
 Sequential d, Sequential e, Sequential f, Sequential g) =>
(Element a
 -> Element b
 -> Element c
 -> Element d
 -> Element e
 -> Element f
 -> Element g
 -> Element col)
-> a -> b -> c -> d -> e -> f -> g -> col
zipWith7 (,,,,,,)

  -- | 'unzip' transforms a collection of pairs into a collection of first
  --   components and a collection of second components.
  unzip :: (Sequential a, Sequential b, Element col ~ (Element a, Element b))
        => col -> (a, b)
  unzip = [(Element a, Element b)] -> (a, b)
forall a b.
(Sequential a, Sequential b) =>
[(Element a, Element b)] -> (a, b)
go ([(Element a, Element b)] -> (a, b))
-> (col -> [(Element a, Element b)]) -> col -> (a, b)
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. col -> [(Element a, Element b)]
forall l. IsList l => l -> [Item l]
toList
    where go :: [(Element a, Element b)] -> (a, b)
go []          = (a
forall a. Monoid a => a
mempty, b
forall a. Monoid a => a
mempty)
          go ((a :: Element a
a, b :: Element b
b):xs :: [(Element a, Element b)]
xs) =
              let (as :: a
as, bs :: b
bs) = [(Element a, Element b)] -> (a, b)
go [(Element a, Element b)]
xs
              in (Element a
a Element a -> a -> a
forall c. Sequential c => Element c -> c -> c
`cons` a
as, Element b
b Element b -> b -> b
forall c. Sequential c => Element c -> c -> c
`cons` b
bs)

  -- | Like 'unzip', but works on a collection of 3-element tuples.
  unzip3 :: ( Sequential a, Sequential b, Sequential c
            , Element col ~ (Element a, Element b, Element c) )
         => col -> (a, b, c)
  unzip3 = [(Element a, Element b, Element c)] -> (a, b, c)
forall a b c.
(Sequential a, Sequential b, Sequential c) =>
[(Element a, Element b, Element c)] -> (a, b, c)
go ([(Element a, Element b, Element c)] -> (a, b, c))
-> (col -> [(Element a, Element b, Element c)]) -> col -> (a, b, c)
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. col -> [(Element a, Element b, Element c)]
forall l. IsList l => l -> [Item l]
toList
    where go :: [(Element a, Element b, Element c)] -> (a, b, c)
go [] = (a
forall a. Monoid a => a
mempty, b
forall a. Monoid a => a
mempty, c
forall a. Monoid a => a
mempty)
          go ((a :: Element a
a, b :: Element b
b, c :: Element c
c):xs :: [(Element a, Element b, Element c)]
xs) =
              let (as :: a
as, bs :: b
bs, cs :: c
cs) = [(Element a, Element b, Element c)] -> (a, b, c)
go [(Element a, Element b, Element c)]
xs
              in (Element a
a Element a -> a -> a
forall c. Sequential c => Element c -> c -> c
`cons` a
as, Element b
b Element b -> b -> b
forall c. Sequential c => Element c -> c -> c
`cons` b
bs, Element c
c Element c -> c -> c
forall c. Sequential c => Element c -> c -> c
`cons` c
cs)

  -- | Like 'unzip', but works on a collection of 4-element tuples.
  unzip4 :: ( Sequential a, Sequential b, Sequential c, Sequential d
            , Element col ~ (Element a, Element b, Element c, Element d) )
         => col -> (a, b, c, d)
  unzip4 = [(Element a, Element b, Element c, Element d)] -> (a, b, c, d)
forall a b c d.
(Sequential a, Sequential b, Sequential c, Sequential d) =>
[(Element a, Element b, Element c, Element d)] -> (a, b, c, d)
go ([(Element a, Element b, Element c, Element d)] -> (a, b, c, d))
-> (col -> [(Element a, Element b, Element c, Element d)])
-> col
-> (a, b, c, d)
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. col -> [(Element a, Element b, Element c, Element d)]
forall l. IsList l => l -> [Item l]
toList
    where go :: [(Element a, Element b, Element c, Element d)] -> (a, b, c, d)
go [] = (a
forall a. Monoid a => a
mempty, b
forall a. Monoid a => a
mempty, c
forall a. Monoid a => a
mempty, d
forall a. Monoid a => a
mempty)
          go ((a :: Element a
a, b :: Element b
b, c :: Element c
c, d :: Element d
d):xs :: [(Element a, Element b, Element c, Element d)]
xs) =
              let (as :: a
as, bs :: b
bs, cs :: c
cs, ds :: d
ds) = [(Element a, Element b, Element c, Element d)] -> (a, b, c, d)
go [(Element a, Element b, Element c, Element d)]
xs
              in (Element a
a Element a -> a -> a
forall c. Sequential c => Element c -> c -> c
`cons` a
as, Element b
b Element b -> b -> b
forall c. Sequential c => Element c -> c -> c
`cons` b
bs, Element c
c Element c -> c -> c
forall c. Sequential c => Element c -> c -> c
`cons` c
cs, Element d
d Element d -> d -> d
forall c. Sequential c => Element c -> c -> c
`cons` d
ds)

  -- | Like 'unzip', but works on a collection of 5-element tuples.
  unzip5 :: ( Sequential a, Sequential b, Sequential c, Sequential d, Sequential e
            , Element col ~ (Element a, Element b, Element c, Element d, Element e) )
         => col -> (a, b, c, d, e)
  unzip5 = [(Element a, Element b, Element c, Element d, Element e)]
-> (a, b, c, d, e)
forall a b c d e.
(Sequential a, Sequential b, Sequential c, Sequential d,
 Sequential e) =>
[(Element a, Element b, Element c, Element d, Element e)]
-> (a, b, c, d, e)
go ([(Element a, Element b, Element c, Element d, Element e)]
 -> (a, b, c, d, e))
-> (col
    -> [(Element a, Element b, Element c, Element d, Element e)])
-> col
-> (a, b, c, d, e)
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. col -> [(Element a, Element b, Element c, Element d, Element e)]
forall l. IsList l => l -> [Item l]
toList
    where go :: [(Element a, Element b, Element c, Element d, Element e)]
-> (a, b, c, d, e)
go [] = (a
forall a. Monoid a => a
mempty, b
forall a. Monoid a => a
mempty, c
forall a. Monoid a => a
mempty, d
forall a. Monoid a => a
mempty, e
forall a. Monoid a => a
mempty)
          go ((a :: Element a
a, b :: Element b
b, c :: Element c
c, d :: Element d
d, e :: Element e
e):xs :: [(Element a, Element b, Element c, Element d, Element e)]
xs) =
              let (as :: a
as, bs :: b
bs, cs :: c
cs, ds :: d
ds, es :: e
es) = [(Element a, Element b, Element c, Element d, Element e)]
-> (a, b, c, d, e)
go [(Element a, Element b, Element c, Element d, Element e)]
xs
              in (Element a
a Element a -> a -> a
forall c. Sequential c => Element c -> c -> c
`cons` a
as, Element b
b Element b -> b -> b
forall c. Sequential c => Element c -> c -> c
`cons` b
bs, Element c
c Element c -> c -> c
forall c. Sequential c => Element c -> c -> c
`cons` c
cs, Element d
d Element d -> d -> d
forall c. Sequential c => Element c -> c -> c
`cons` d
ds, Element e
e Element e -> e -> e
forall c. Sequential c => Element c -> c -> c
`cons` e
es)

  -- | Like 'unzip', but works on a collection of 6-element tuples.
  unzip6 :: ( Sequential a, Sequential b, Sequential c, Sequential d, Sequential e, Sequential f
            , Element col ~ (Element a, Element b, Element c, Element d, Element e, Element f) )
         => col -> (a, b, c, d, e, f)
  unzip6 = [(Element a, Element b, Element c, Element d, Element e,
  Element f)]
-> (a, b, c, d, e, f)
forall a b c d e f.
(Sequential a, Sequential b, Sequential c, Sequential d,
 Sequential e, Sequential f) =>
[(Element a, Element b, Element c, Element d, Element e,
  Element f)]
-> (a, b, c, d, e, f)
go ([(Element a, Element b, Element c, Element d, Element e,
   Element f)]
 -> (a, b, c, d, e, f))
-> (col
    -> [(Element a, Element b, Element c, Element d, Element e,
         Element f)])
-> col
-> (a, b, c, d, e, f)
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. col
-> [(Element a, Element b, Element c, Element d, Element e,
     Element f)]
forall l. IsList l => l -> [Item l]
toList
    where go :: [(Element a, Element b, Element c, Element d, Element e,
  Element f)]
-> (a, b, c, d, e, f)
go [] = (a
forall a. Monoid a => a
mempty, b
forall a. Monoid a => a
mempty, c
forall a. Monoid a => a
mempty, d
forall a. Monoid a => a
mempty, e
forall a. Monoid a => a
mempty, f
forall a. Monoid a => a
mempty)
          go ((a :: Element a
a, b :: Element b
b, c :: Element c
c, d :: Element d
d, e :: Element e
e, f :: Element f
f):xs :: [(Element a, Element b, Element c, Element d, Element e,
  Element f)]
xs) =
              let (as :: a
as, bs :: b
bs, cs :: c
cs, ds :: d
ds, es :: e
es, fs :: f
fs) = [(Element a, Element b, Element c, Element d, Element e,
  Element f)]
-> (a, b, c, d, e, f)
go [(Element a, Element b, Element c, Element d, Element e,
  Element f)]
xs
              in (Element a
a Element a -> a -> a
forall c. Sequential c => Element c -> c -> c
`cons` a
as, Element b
b Element b -> b -> b
forall c. Sequential c => Element c -> c -> c
`cons` b
bs, Element c
c Element c -> c -> c
forall c. Sequential c => Element c -> c -> c
`cons` c
cs, Element d
d Element d -> d -> d
forall c. Sequential c => Element c -> c -> c
`cons` d
ds, Element e
e Element e -> e -> e
forall c. Sequential c => Element c -> c -> c
`cons` e
es, Element f
f Element f -> f -> f
forall c. Sequential c => Element c -> c -> c
`cons` f
fs)

  -- | Like 'unzip', but works on a collection of 7-element tuples.
  unzip7 :: ( Sequential a, Sequential b, Sequential c, Sequential d, Sequential e, Sequential f, Sequential g
            , Element col ~ (Element a, Element b, Element c, Element d, Element e, Element f, Element g) )
        => col -> (a, b, c, d, e, f, g)
  unzip7 = [(Element a, Element b, Element c, Element d, Element e, Element f,
  Element g)]
-> (a, b, c, d, e, f, g)
forall a b c d e f g.
(Sequential a, Sequential b, Sequential c, Sequential d,
 Sequential e, Sequential f, Sequential g) =>
[(Element a, Element b, Element c, Element d, Element e, Element f,
  Element g)]
-> (a, b, c, d, e, f, g)
go ([(Element a, Element b, Element c, Element d, Element e,
   Element f, Element g)]
 -> (a, b, c, d, e, f, g))
-> (col
    -> [(Element a, Element b, Element c, Element d, Element e,
         Element f, Element g)])
-> col
-> (a, b, c, d, e, f, g)
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. col
-> [(Element a, Element b, Element c, Element d, Element e,
     Element f, Element g)]
forall l. IsList l => l -> [Item l]
toList
    where go :: [(Element a, Element b, Element c, Element d, Element e, Element f,
  Element g)]
-> (a, b, c, d, e, f, g)
go [] = (a
forall a. Monoid a => a
mempty, b
forall a. Monoid a => a
mempty, c
forall a. Monoid a => a
mempty, d
forall a. Monoid a => a
mempty, e
forall a. Monoid a => a
mempty, f
forall a. Monoid a => a
mempty, g
forall a. Monoid a => a
mempty)
          go ((a :: Element a
a, b :: Element b
b, c :: Element c
c, d :: Element d
d, e :: Element e
e, f :: Element f
f, g :: Element g
g):xs :: [(Element a, Element b, Element c, Element d, Element e, Element f,
  Element g)]
xs) =
              let (as :: a
as, bs :: b
bs, cs :: c
cs, ds :: d
ds, es :: e
es, fs :: f
fs, gs :: g
gs) = [(Element a, Element b, Element c, Element d, Element e, Element f,
  Element g)]
-> (a, b, c, d, e, f, g)
go [(Element a, Element b, Element c, Element d, Element e, Element f,
  Element g)]
xs
              in (Element a
a Element a -> a -> a
forall c. Sequential c => Element c -> c -> c
`cons` a
as, Element b
b Element b -> b -> b
forall c. Sequential c => Element c -> c -> c
`cons` b
bs, Element c
c Element c -> c -> c
forall c. Sequential c => Element c -> c -> c
`cons` c
cs, Element d
d Element d -> d -> d
forall c. Sequential c => Element c -> c -> c
`cons` d
ds, Element e
e Element e -> e -> e
forall c. Sequential c => Element c -> c -> c
`cons` e
es, Element f
f Element f -> f -> f
forall c. Sequential c => Element c -> c -> c
`cons` f
fs, Element g
g Element g -> g -> g
forall c. Sequential c => Element c -> c -> c
`cons` g
gs)

instance BoxedZippable [a]
instance BoxedZippable (BA.Array ty)


-- * Tuple helper functions

uncons2 :: (Sequential a, Sequential b) => (a, b) -> Maybe ((Element a, Element b), (a, b))
uncons2 :: (a, b) -> Maybe ((Element a, Element b), (a, b))
uncons2 xs :: (a, b)
xs = let (as :: a
as, bs :: b
bs) = (a, b)
xs
             in do (a' :: Element a
a', as' :: a
as') <- a -> Maybe (Element a, a)
forall c. Sequential c => c -> Maybe (Element c, c)
uncons a
as
                   (b' :: Element b
b', bs' :: b
bs') <- b -> Maybe (Element b, b)
forall c. Sequential c => c -> Maybe (Element c, c)
uncons b
bs
                   ((Element a, Element b), (a, b))
-> Maybe ((Element a, Element b), (a, b))
forall (m :: * -> *) a. Monad m => a -> m a
return ((Element a
a', Element b
b'), (a
as', b
bs'))

uncons3 :: (Sequential a, Sequential b, Sequential c)
        => (a, b, c)
        -> Maybe ((Element a, Element b, Element c), (a, b, c))
uncons3 :: (a, b, c) -> Maybe ((Element a, Element b, Element c), (a, b, c))
uncons3 xs :: (a, b, c)
xs = let (as :: a
as, bs :: b
bs, cs :: c
cs) = (a, b, c)
xs
             in do (a' :: Element a
a', as' :: a
as') <- a -> Maybe (Element a, a)
forall c. Sequential c => c -> Maybe (Element c, c)
uncons a
as
                   (b' :: Element b
b', bs' :: b
bs') <- b -> Maybe (Element b, b)
forall c. Sequential c => c -> Maybe (Element c, c)
uncons b
bs
                   (c' :: Element c
c', cs' :: c
cs') <- c -> Maybe (Element c, c)
forall c. Sequential c => c -> Maybe (Element c, c)
uncons c
cs
                   ((Element a, Element b, Element c), (a, b, c))
-> Maybe ((Element a, Element b, Element c), (a, b, c))
forall (m :: * -> *) a. Monad m => a -> m a
return ((Element a
a', Element b
b', Element c
c'), (a
as', b
bs', c
cs'))

uncons4 :: (Sequential a, Sequential b, Sequential c, Sequential d)
        => (a, b, c, d)
        -> Maybe ( (Element a, Element b, Element c, Element d)
                 , (a, b, c, d) )
uncons4 :: (a, b, c, d)
-> Maybe
     ((Element a, Element b, Element c, Element d), (a, b, c, d))
uncons4 xs :: (a, b, c, d)
xs = let (as :: a
as, bs :: b
bs, cs :: c
cs, ds :: d
ds) = (a, b, c, d)
xs
             in do (a' :: Element a
a', as' :: a
as') <- a -> Maybe (Element a, a)
forall c. Sequential c => c -> Maybe (Element c, c)
uncons a
as
                   (b' :: Element b
b', bs' :: b
bs') <- b -> Maybe (Element b, b)
forall c. Sequential c => c -> Maybe (Element c, c)
uncons b
bs
                   (c' :: Element c
c', cs' :: c
cs') <- c -> Maybe (Element c, c)
forall c. Sequential c => c -> Maybe (Element c, c)
uncons c
cs
                   (d' :: Element d
d', ds' :: d
ds') <- d -> Maybe (Element d, d)
forall c. Sequential c => c -> Maybe (Element c, c)
uncons d
ds
                   ((Element a, Element b, Element c, Element d), (a, b, c, d))
-> Maybe
     ((Element a, Element b, Element c, Element d), (a, b, c, d))
forall (m :: * -> *) a. Monad m => a -> m a
return ((Element a
a', Element b
b', Element c
c', Element d
d'), (a
as', b
bs', c
cs', d
ds'))

uncons5 :: (Sequential a, Sequential b, Sequential c, Sequential d, Sequential e)
        => (a, b, c, d, e)
        -> Maybe ( (Element a, Element b, Element c, Element d, Element e)
                 , (a, b, c, d, e) )
uncons5 :: (a, b, c, d, e)
-> Maybe
     ((Element a, Element b, Element c, Element d, Element e),
      (a, b, c, d, e))
uncons5 xs :: (a, b, c, d, e)
xs = let (as :: a
as, bs :: b
bs, cs :: c
cs, ds :: d
ds, es :: e
es) = (a, b, c, d, e)
xs
             in do (a' :: Element a
a', as' :: a
as') <- a -> Maybe (Element a, a)
forall c. Sequential c => c -> Maybe (Element c, c)
uncons a
as
                   (b' :: Element b
b', bs' :: b
bs') <- b -> Maybe (Element b, b)
forall c. Sequential c => c -> Maybe (Element c, c)
uncons b
bs
                   (c' :: Element c
c', cs' :: c
cs') <- c -> Maybe (Element c, c)
forall c. Sequential c => c -> Maybe (Element c, c)
uncons c
cs
                   (d' :: Element d
d', ds' :: d
ds') <- d -> Maybe (Element d, d)
forall c. Sequential c => c -> Maybe (Element c, c)
uncons d
ds
                   (e' :: Element e
e', es' :: e
es') <- e -> Maybe (Element e, e)
forall c. Sequential c => c -> Maybe (Element c, c)
uncons e
es
                   ((Element a, Element b, Element c, Element d, Element e),
 (a, b, c, d, e))
-> Maybe
     ((Element a, Element b, Element c, Element d, Element e),
      (a, b, c, d, e))
forall (m :: * -> *) a. Monad m => a -> m a
return ((Element a
a', Element b
b', Element c
c', Element d
d', Element e
e'), (a
as', b
bs', c
cs', d
ds', e
es'))

uncons6 :: ( Sequential a, Sequential b, Sequential c, Sequential d, Sequential e
           , Sequential f )
        => (a, b, c, d, e, f)
        -> Maybe ( (Element a, Element b, Element c, Element d, Element e, Element f)
                 , (a, b, c, d, e, f) )
uncons6 :: (a, b, c, d, e, f)
-> Maybe
     ((Element a, Element b, Element c, Element d, Element e,
       Element f),
      (a, b, c, d, e, f))
uncons6 xs :: (a, b, c, d, e, f)
xs = let (as :: a
as, bs :: b
bs, cs :: c
cs, ds :: d
ds, es :: e
es, fs :: f
fs) = (a, b, c, d, e, f)
xs
             in do (a' :: Element a
a', as' :: a
as') <- a -> Maybe (Element a, a)
forall c. Sequential c => c -> Maybe (Element c, c)
uncons a
as
                   (b' :: Element b
b', bs' :: b
bs') <- b -> Maybe (Element b, b)
forall c. Sequential c => c -> Maybe (Element c, c)
uncons b
bs
                   (c' :: Element c
c', cs' :: c
cs') <- c -> Maybe (Element c, c)
forall c. Sequential c => c -> Maybe (Element c, c)
uncons c
cs
                   (d' :: Element d
d', ds' :: d
ds') <- d -> Maybe (Element d, d)
forall c. Sequential c => c -> Maybe (Element c, c)
uncons d
ds
                   (e' :: Element e
e', es' :: e
es') <- e -> Maybe (Element e, e)
forall c. Sequential c => c -> Maybe (Element c, c)
uncons e
es
                   (f' :: Element f
f', fs' :: f
fs') <- f -> Maybe (Element f, f)
forall c. Sequential c => c -> Maybe (Element c, c)
uncons f
fs
                   ((Element a, Element b, Element c, Element d, Element e,
  Element f),
 (a, b, c, d, e, f))
-> Maybe
     ((Element a, Element b, Element c, Element d, Element e,
       Element f),
      (a, b, c, d, e, f))
forall (m :: * -> *) a. Monad m => a -> m a
return ((Element a
a', Element b
b', Element c
c', Element d
d', Element e
e', Element f
f'), (a
as', b
bs', c
cs', d
ds', e
es', f
fs'))

uncons7 :: ( Sequential a, Sequential b, Sequential c, Sequential d, Sequential e
           , Sequential f, Sequential g )
        => (a, b, c, d, e, f, g)
        -> Maybe ( (Element a, Element b, Element c, Element d, Element e, Element f
                 , Element g)
                 , (a, b, c, d, e, f, g) )
uncons7 :: (a, b, c, d, e, f, g)
-> Maybe
     ((Element a, Element b, Element c, Element d, Element e, Element f,
       Element g),
      (a, b, c, d, e, f, g))
uncons7 xs :: (a, b, c, d, e, f, g)
xs = let (as :: a
as, bs :: b
bs, cs :: c
cs, ds :: d
ds, es :: e
es, fs :: f
fs, gs :: g
gs) = (a, b, c, d, e, f, g)
xs
             in do (a' :: Element a
a', as' :: a
as') <- a -> Maybe (Element a, a)
forall c. Sequential c => c -> Maybe (Element c, c)
uncons a
as
                   (b' :: Element b
b', bs' :: b
bs') <- b -> Maybe (Element b, b)
forall c. Sequential c => c -> Maybe (Element c, c)
uncons b
bs
                   (c' :: Element c
c', cs' :: c
cs') <- c -> Maybe (Element c, c)
forall c. Sequential c => c -> Maybe (Element c, c)
uncons c
cs
                   (d' :: Element d
d', ds' :: d
ds') <- d -> Maybe (Element d, d)
forall c. Sequential c => c -> Maybe (Element c, c)
uncons d
ds
                   (e' :: Element e
e', es' :: e
es') <- e -> Maybe (Element e, e)
forall c. Sequential c => c -> Maybe (Element c, c)
uncons e
es
                   (f' :: Element f
f', fs' :: f
fs') <- f -> Maybe (Element f, f)
forall c. Sequential c => c -> Maybe (Element c, c)
uncons f
fs
                   (g' :: Element g
g', gs' :: g
gs') <- g -> Maybe (Element g, g)
forall c. Sequential c => c -> Maybe (Element c, c)
uncons g
gs
                   ((Element a, Element b, Element c, Element d, Element e, Element f,
  Element g),
 (a, b, c, d, e, f, g))
-> Maybe
     ((Element a, Element b, Element c, Element d, Element e, Element f,
       Element g),
      (a, b, c, d, e, f, g))
forall (m :: * -> *) a. Monad m => a -> m a
return ( (Element a
a', Element b
b', Element c
c', Element d
d', Element e
e', Element f
f', Element g
g')
                          , (a
as', b
bs', c
cs', d
ds', e
es', f
fs', g
gs') )

uncurry2 :: (a -> b -> c) -> (a, b) -> c
uncurry2 :: (a -> b -> c) -> (a, b) -> c
uncurry2 = (a -> b -> c) -> (a, b) -> c
forall a b c. (a -> b -> c) -> (a, b) -> c
Prelude.uncurry

uncurry3 :: (a -> b -> c -> d) -> (a, b, c) -> d
uncurry3 :: (a -> b -> c -> d) -> (a, b, c) -> d
uncurry3 fn :: a -> b -> c -> d
fn (a :: a
a, b :: b
b, c :: c
c) = a -> b -> c -> d
fn a
a b
b c
c

uncurry4 :: (a -> b -> c -> d -> g) -> (a, b, c, d) -> g
uncurry4 :: (a -> b -> c -> d -> g) -> (a, b, c, d) -> g
uncurry4 fn :: a -> b -> c -> d -> g
fn (a :: a
a, b :: b
b, c :: c
c, d :: d
d) = a -> b -> c -> d -> g
fn a
a b
b c
c d
d

uncurry5 :: (a -> b -> c -> d -> e -> f) -> (a, b, c, d, e) -> f
uncurry5 :: (a -> b -> c -> d -> e -> f) -> (a, b, c, d, e) -> f
uncurry5 fn :: a -> b -> c -> d -> e -> f
fn (a :: a
a, b :: b
b, c :: c
c, d :: d
d, e :: e
e) = a -> b -> c -> d -> e -> f
fn a
a b
b c
c d
d e
e

uncurry6 :: (a -> b -> c -> d -> e -> f -> g) -> (a, b, c, d, e, f) -> g
uncurry6 :: (a -> b -> c -> d -> e -> f -> g) -> (a, b, c, d, e, f) -> g
uncurry6 fn :: a -> b -> c -> d -> e -> f -> g
fn (a :: a
a, b :: b
b, c :: c
c, d :: d
d, e :: e
e, f :: f
f) = a -> b -> c -> d -> e -> f -> g
fn a
a b
b c
c d
d e
e f
f

uncurry7 :: (a -> b -> c -> d -> e -> f -> g -> h) -> (a, b, c, d, e, f, g) -> h
uncurry7 :: (a -> b -> c -> d -> e -> f -> g -> h)
-> (a, b, c, d, e, f, g) -> h
uncurry7 fn :: a -> b -> c -> d -> e -> f -> g -> h
fn (a :: a
a, b :: b
b, c :: c
c, d :: d
d, e :: e
e, f :: f
f, g :: g
g) = a -> b -> c -> d -> e -> f -> g -> h
fn a
a b
b c
c d
d e
e f
f g
g