    -- |
    -- 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 #-}
    {-# LANGUAGE TypeOperators #-}
    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 Element a -> Element b -> Element col
    f a
    a b
    b = (Element [Element a] -> Element [Element b] -> Element col)
    -> ([Element a], [Element b]) -> col
    forall {a} {b} {c}.
    (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 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 (\((Element a, Element b)
    x, (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 b c a. (b -> c) -> (a -> b) -> a -> 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 Element a -> Element b -> Element c -> Element col
    f a
    a b
    b c
    c = (Element [Element a]
     -> Element [Element b] -> Element [Element c] -> Element col)
    -> ([Element a], [Element b], [Element c]) -> col
    forall {c} {b} {a} {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 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 (\((Element a, Element b, Element c)
    x, (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 b c a. (b -> c) -> (a -> b) -> a -> 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 Element a -> Element b -> Element c -> Element d -> Element col
    fn a
    a b
    b c
    c 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 {d} {c} {b} {a} {c}.
    (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 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 (\((Element a, Element b, Element c, Element d)
    x, (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 b c a. (b -> c) -> (a -> b) -> a -> 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 Element a
    -> Element b -> Element c -> Element d -> Element e -> Element col
    fn a
    a b
    b c
    c d
    d 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 {d} {a} {b} {e} {c} {c}.
    (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 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 (\((Element a, Element b, Element c, Element d, Element e)
    x, (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 b c a. (b -> c) -> (a -> b) -> a -> 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 Element a
    -> Element b
    -> Element c
    -> Element d
    -> Element e
    -> Element f
    -> Element col
    fn a
    a b
    b c
    c d
    d e
    e 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 {d} {a} {f} {b} {c} {e} {c}.
    (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 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 (\((Element a, Element b, Element c, Element d, Element e, Element f)
    x, (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 b c a. (b -> c) -> (a -> b) -> a -> 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 Element a
    -> Element b
    -> Element c
    -> Element d
    -> Element e
    -> Element f
    -> Element g
    -> Element col
    fn a
    a b
    b c
    c d
    d e
    e f
    f 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 {d} {c} {e} {b} {f} {a} {g} {c}.
    (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 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 (\((Element a, Element b, Element c, Element d, Element e, Element f,
     Element g)
    x, (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 b c a. (b -> c) -> (a -> b) -> a -> 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 :: forall a b.
    (Sequential a, Sequential b) =>
    (Element a -> Element b -> Element (UArray ty))
    -> a -> b -> UArray ty
    zipWith Element a -> Element b -> Element (UArray ty)
    f a
    as 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_ Int
    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 t -> t -> ty
    _  []       [t]
    _        = () -> Builder (UArray ty) (MUArray ty) ty state err ()
    forall a. a -> Builder (UArray ty) (MUArray ty) ty state err a
    forall (m :: * -> *) a. Monad m => a -> m a
    return ()
          go t -> t -> ty
    _  [t]
    _        []       = () -> Builder (UArray ty) (MUArray ty) ty state err ()
    forall a. a -> Builder (UArray ty) (MUArray ty) ty state err a
    forall (m :: * -> *) a. Monad m => a -> m a
    return ()
          go t -> t -> ty
    f' (t
    a':[t]
    as') (t
    b':[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 a b.
    Builder (UArray ty) (MUArray ty) ty state err a
    -> Builder (UArray ty) (MUArray ty) ty state err b
    -> Builder (UArray ty) (MUArray ty) ty state err b
    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 :: forall a b.
    (Sequential a, Sequential b) =>
    (Element a -> Element b -> Element (Array ty))
    -> a -> b -> Array ty
    zipWith Element a -> Element b -> Element (Array ty)
    f a
    as 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_ Int
    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 t -> t -> ty
    _  []       [t]
    _        = () -> Builder (Array ty) (MArray ty) ty state err ()
    forall a. a -> Builder (Array ty) (MArray ty) ty state err a
    forall (m :: * -> *) a. Monad m => a -> m a
    return ()
          go t -> t -> ty
    _  [t]
    _        []       = () -> Builder (Array ty) (MArray ty) ty state err ()
    forall a. a -> Builder (Array ty) (MArray ty) ty state err a
    forall (m :: * -> *) a. Monad m => a -> m a
    return ()
          go t -> t -> ty
    f' (t
    a':[t]
    as') (t
    b':[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 a b.
    Builder (Array ty) (MArray ty) ty state err a
    -> Builder (Array ty) (MArray ty) ty state err b
    -> Builder (Array ty) (MArray ty) ty state err b
    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 :: forall a b.
    (Sequential a, Sequential b) =>
    (Element a -> Element b -> Element String) -> a -> b -> String
    zipWith Element a -> Element b -> Element String
    f a
    as 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_ Int
    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 t -> t -> Char
    _  []       [t]
    _        = () -> Builder String MutableString Word8 state err ()
    forall a. a -> Builder String MutableString Word8 state err a
    forall (m :: * -> *) a. Monad m => a -> m a
    return ()
          go t -> t -> Char
    _  [t]
    _        []       = () -> Builder String MutableString Word8 state err ()
    forall a. a -> Builder String MutableString Word8 state err a
    forall (m :: * -> *) a. Monad m => a -> m a
    return ()
          go t -> t -> Char
    f' (t
    a':[t]
    as') (t
    b':[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 a b.
    Builder String MutableString Word8 state err a
    -> Builder String MutableString Word8 state err b
    -> Builder String MutableString Word8 state err b
    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
    forall a b.
    (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
    forall a b c.
    (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
    forall a b c d.
    (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
    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 -> 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
    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
     -> 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
    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
     -> 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 {b} {a}.
    (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 b c a. (b -> c) -> (a -> b) -> a -> 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)]
    col -> [Item col]
    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 ((Element a
    a, Element b
    b):[(Element a, Element b)]
    xs) =
                  let (a
    as, 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 {b} {c} {a}.
    (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 b c a. (b -> c) -> (a -> b) -> a -> 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)]
    col -> [Item col]
    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 ((Element a
    a, Element b
    b, Element c
    c):[(Element a, Element b, Element c)]
    xs) =
                  let (a
    as, b
    bs, 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 {d} {c} {b} {a}.
    (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 b c a. (b -> c) -> (a -> b) -> a -> 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, Element d)]
    col -> [Item col]
    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 ((Element a
    a, Element b
    b, Element c
    c, Element d
    d):[(Element a, Element b, Element c, Element d)]
    xs) =
                  let (a
    as, b
    bs, c
    cs, 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 {e} {d} {c} {b} {a}.
    (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 b c a. (b -> c) -> (a -> b) -> a -> 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, Element d, Element e)]
    col -> [Item col]
    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 ((Element a
    a, Element b
    b, Element c
    c, Element d
    d, Element e
    e):[(Element a, Element b, Element c, Element d, Element e)]
    xs) =
                  let (a
    as, b
    bs, c
    cs, d
    ds, 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 {e} {b} {c} {f} {d} {a}.
    (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 b c a. (b -> c) -> (a -> b) -> a -> 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, Element d, Element e,
         Element f)]
    col -> [Item col]
    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 ((Element a
    a, Element b
    b, Element c
    c, Element d
    d, Element e
    e, Element f
    f):[(Element a, Element b, Element c, Element d, Element e,
      Element f)]
    xs) =
                  let (a
    as, b
    bs, c
    cs, d
    ds, e
    es, 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 {e} {b} {g} {c} {d} {f} {a}.
    (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 b c a. (b -> c) -> (a -> b) -> a -> 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, Element d, Element e,
         Element f, Element g)]
    col -> [Item col]
    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 ((Element a
    a, Element b
    b, Element c
    c, Element d
    d, Element e
    e, Element f
    f, Element g
    g):[(Element a, Element b, Element c, Element d, Element e, Element f,
      Element g)]
    xs) =
                  let (a
    as, b
    bs, c
    cs, d
    ds, e
    es, f
    fs, 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 :: forall a b.
    (Sequential a, Sequential b) =>
    (a, b) -> Maybe ((Element a, Element b), (a, b))
    uncons2 (a, b)
    xs = let (a
    as, b
    bs) = (a, b)
    xs
                 in do (a', as') <- a -> Maybe (Element a, a)
    forall c. Sequential c => c -> Maybe (Element c, c)
    uncons a
    as
                       (b', bs') <- uncons bs
                       return ((a', b'), (as', bs'))

    uncons3 :: (Sequential a, Sequential b, Sequential c)
            => (a, b, c)
            -> Maybe ((Element a, Element b, Element c), (a, b, c))
    uncons3 :: forall a b c.
    (Sequential a, Sequential b, Sequential c) =>
    (a, b, c) -> Maybe ((Element a, Element b, Element c), (a, b, c))
    uncons3 (a, b, c)
    xs = let (a
    as, b
    bs, c
    cs) = (a, b, c)
    xs
                 in do (a', as') <- a -> Maybe (Element a, a)
    forall c. Sequential c => c -> Maybe (Element c, c)
    uncons a
    as
                       (b', bs') <- uncons bs
                       (c', cs') <- uncons cs
                       return ((a', b', c'), (as', bs', 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 :: 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 (a, b, c, d)
    xs = let (a
    as, b
    bs, c
    cs, d
    ds) = (a, b, c, d)
    xs
                 in do (a', as') <- a -> Maybe (Element a, a)
    forall c. Sequential c => c -> Maybe (Element c, c)
    uncons a
    as
                       (b', bs') <- uncons bs
                       (c', cs') <- uncons cs
                       (d', ds') <- uncons ds
                       return ((a', b', c', d'), (as', bs', cs', 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 :: 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 (a, b, c, d, e)
    xs = let (a
    as, b
    bs, c
    cs, d
    ds, e
    es) = (a, b, c, d, e)
    xs
                 in do (a', as') <- a -> Maybe (Element a, a)
    forall c. Sequential c => c -> Maybe (Element c, c)
    uncons a
    as
                       (b', bs') <- uncons bs
                       (c', cs') <- uncons cs
                       (d', ds') <- uncons ds
                       (e', es') <- uncons es
                       return ((a', b', c', d', e'), (as', bs', cs', ds', 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 :: 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 (a, b, c, d, e, f)
    xs = let (a
    as, b
    bs, c
    cs, d
    ds, e
    es, f
    fs) = (a, b, c, d, e, f)
    xs
                 in do (a', as') <- a -> Maybe (Element a, a)
    forall c. Sequential c => c -> Maybe (Element c, c)
    uncons a
    as
                       (b', bs') <- uncons bs
                       (c', cs') <- uncons cs
                       (d', ds') <- uncons ds
                       (e', es') <- uncons es
                       (f', fs') <- uncons fs
                       return ((a', b', c', d', e', f'), (as', bs', cs', ds', es', 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 :: 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 (a, b, c, d, e, f, g)
    xs = let (a
    as, b
    bs, c
    cs, d
    ds, e
    es, f
    fs, g
    gs) = (a, b, c, d, e, f, g)
    xs
                 in do (a', as') <- a -> Maybe (Element a, a)
    forall c. Sequential c => c -> Maybe (Element c, c)
    uncons a
    as
                       (b', bs') <- uncons bs
                       (c', cs') <- uncons cs
                       (d', ds') <- uncons ds
                       (e', es') <- uncons es
                       (f', fs') <- uncons fs
                       (g', gs') <- uncons gs
                       return ( (a', b', c', d', e', f', g')
                              , (as', bs', cs', ds', es', fs', gs') )

    uncurry2 :: (a -> b -> c) -> (a, b) -> c
    uncurry2 :: forall a b c. (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 :: forall a b c d. (a -> b -> c -> d) -> (a, b, c) -> d
    uncurry3 a -> b -> c -> d
    fn (a
    a, b
    b, 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 :: forall a b c d g. (a -> b -> c -> d -> g) -> (a, b, c, d) -> g
    uncurry4 a -> b -> c -> d -> g
    fn (a
    a, b
    b, c
    c, 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 :: forall a b c d e f.
    (a -> b -> c -> d -> e -> f) -> (a, b, c, d, e) -> f
    uncurry5 a -> b -> c -> d -> e -> f
    fn (a
    a, b
    b, c
    c, d
    d, 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 :: forall a b c d e f g.
    (a -> b -> c -> d -> e -> f -> g) -> (a, b, c, d, e, f) -> g
    uncurry6 a -> b -> c -> d -> e -> f -> g
    fn (a
    a, b
    b, c
    c, d
    d, e
    e, 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 :: 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 a -> b -> c -> d -> e -> f -> g -> h
    fn (a
    a, b
    b, c
    c, d
    d, e
    e, f
    f, 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