    -- |
    -- Module      : Foundation.Array.Chunked.Unboxed
    -- License     : BSD-style -- Maintainer  : Alfredo Di Napoli <alfredo.dinapoli@gmail.com>
    -- Stability   : experimental
    -- Portability : portable
    --
    -- Simple array-of-arrays abstraction
    --
    {-# LANGUAGE MagicHash #-}
    {-# LANGUAGE BangPatterns #-}
    {-# LANGUAGE ExistentialQuantification #-}
    {-# LANGUAGE RankNTypes #-}
    {-# LANGUAGE ScopedTypeVariables #-}
    {-# LANGUAGE ViewPatterns #-}
    module Foundation.Array.Chunked.Unboxed
        ( ChunkedUArray
        ) where

    import           Data.Typeable
    import           Control.Arrow ((***))
    import           Basement.BoxedArray (Array)
    import qualified Basement.BoxedArray as A
    import           Basement.Exception
    import           Basement.UArray (UArray)
    import qualified Basement.UArray as U
    import           Basement.Compat.Bifunctor
    import           Basement.Compat.Semigroup
    import           Basement.Compat.Base
    import           Basement.Types.OffsetSize
    import           Basement.PrimType
    import           GHC.ST

    import           Foundation.Numerical
    import           Foundation.Primitive
    import qualified Foundation.Collection as C

    newtype ChunkedUArray ty = ChunkedUArray (Array (UArray ty))
                          deriving (Int -> ChunkedUArray ty -> ShowS
    [ChunkedUArray ty] -> ShowS
    ChunkedUArray ty -> String
    (Int -> ChunkedUArray ty -> ShowS)
    -> (ChunkedUArray ty -> String)
    -> ([ChunkedUArray ty] -> ShowS)
    -> Show (ChunkedUArray ty)
    forall ty.
    (PrimType ty, Show ty) =>
    Int -> ChunkedUArray ty -> ShowS
    forall ty. (PrimType ty, Show ty) => [ChunkedUArray ty] -> ShowS
    forall ty. (PrimType ty, Show ty) => ChunkedUArray ty -> String
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: forall ty.
    (PrimType ty, Show ty) =>
    Int -> ChunkedUArray ty -> ShowS
    showsPrec :: Int -> ChunkedUArray ty -> ShowS
    $cshow :: forall ty. (PrimType ty, Show ty) => ChunkedUArray ty -> String
    show :: ChunkedUArray ty -> String
    $cshowList :: forall ty. (PrimType ty, Show ty) => [ChunkedUArray ty] -> ShowS
    showList :: [ChunkedUArray ty] -> ShowS
    Show, Eq (ChunkedUArray ty)
    Eq (ChunkedUArray ty)
    -> (ChunkedUArray ty -> ChunkedUArray ty -> Ordering)
    -> (ChunkedUArray ty -> ChunkedUArray ty -> Bool)
    -> (ChunkedUArray ty -> ChunkedUArray ty -> Bool)
    -> (ChunkedUArray ty -> ChunkedUArray ty -> Bool)
    -> (ChunkedUArray ty -> ChunkedUArray ty -> Bool)
    -> (ChunkedUArray ty -> ChunkedUArray ty -> ChunkedUArray ty)
    -> (ChunkedUArray ty -> ChunkedUArray ty -> ChunkedUArray ty)
    -> Ord (ChunkedUArray ty)
    ChunkedUArray ty -> ChunkedUArray ty -> Bool
    ChunkedUArray ty -> ChunkedUArray ty -> Ordering
    ChunkedUArray ty -> ChunkedUArray ty -> ChunkedUArray ty
    forall a.
    Eq a
    -> (a -> a -> Ordering)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> a)
    -> (a -> a -> a)
    -> Ord a
    forall {ty}. (PrimType ty, Ord ty) => Eq (ChunkedUArray ty)
    forall ty.
    (PrimType ty, Ord ty) =>
    ChunkedUArray ty -> ChunkedUArray ty -> Bool
    forall ty.
    (PrimType ty, Ord ty) =>
    ChunkedUArray ty -> ChunkedUArray ty -> Ordering
    forall ty.
    (PrimType ty, Ord ty) =>
    ChunkedUArray ty -> ChunkedUArray ty -> ChunkedUArray ty
    $ccompare :: forall ty.
    (PrimType ty, Ord ty) =>
    ChunkedUArray ty -> ChunkedUArray ty -> Ordering
    compare :: ChunkedUArray ty -> ChunkedUArray ty -> Ordering
    $c< :: forall ty.
    (PrimType ty, Ord ty) =>
    ChunkedUArray ty -> ChunkedUArray ty -> Bool
    < :: ChunkedUArray ty -> ChunkedUArray ty -> Bool
    $c<= :: forall ty.
    (PrimType ty, Ord ty) =>
    ChunkedUArray ty -> ChunkedUArray ty -> Bool
    <= :: ChunkedUArray ty -> ChunkedUArray ty -> Bool
    $c> :: forall ty.
    (PrimType ty, Ord ty) =>
    ChunkedUArray ty -> ChunkedUArray ty -> Bool
    > :: ChunkedUArray ty -> ChunkedUArray ty -> Bool
    $c>= :: forall ty.
    (PrimType ty, Ord ty) =>
    ChunkedUArray ty -> ChunkedUArray ty -> Bool
    >= :: ChunkedUArray ty -> ChunkedUArray ty -> Bool
    $cmax :: forall ty.
    (PrimType ty, Ord ty) =>
    ChunkedUArray ty -> ChunkedUArray ty -> ChunkedUArray ty
    max :: ChunkedUArray ty -> ChunkedUArray ty -> ChunkedUArray ty
    $cmin :: forall ty.
    (PrimType ty, Ord ty) =>
    ChunkedUArray ty -> ChunkedUArray ty -> ChunkedUArray ty
    min :: ChunkedUArray ty -> ChunkedUArray ty -> ChunkedUArray ty
    Ord, Typeable)

    instance PrimType ty => Eq (ChunkedUArray ty) where
      == :: ChunkedUArray ty -> ChunkedUArray ty -> Bool
    (==) = ChunkedUArray ty -> ChunkedUArray ty -> Bool
    forall ty.
    PrimType ty =>
    ChunkedUArray ty -> ChunkedUArray ty -> Bool
    equal
    instance NormalForm (ChunkedUArray ty) where
        toNormalForm :: ChunkedUArray ty -> ()
    toNormalForm (ChunkedUArray Array (UArray ty)
    spine) = Array (UArray ty) -> ()
    forall a. NormalForm a => a -> ()
    toNormalForm Array (UArray ty)
    spine

    instance Semigroup (ChunkedUArray a) where
        <> :: ChunkedUArray a -> ChunkedUArray a -> ChunkedUArray a
    (<>) = ChunkedUArray a -> ChunkedUArray a -> ChunkedUArray a
    forall a. ChunkedUArray a -> ChunkedUArray a -> ChunkedUArray a
    append
    instance Monoid (ChunkedUArray a) where
        mempty :: ChunkedUArray a
    mempty  = ChunkedUArray a
    forall a. ChunkedUArray a
    empty
        mconcat :: [ChunkedUArray a] -> ChunkedUArray a
    mconcat = [ChunkedUArray a] -> ChunkedUArray a
    forall a. [ChunkedUArray a] -> ChunkedUArray a
    concat

    type instance C.Element (ChunkedUArray ty) = ty

    instance PrimType ty => IsList (ChunkedUArray ty) where
        type Item (ChunkedUArray ty) = ty
        fromList :: [Item (ChunkedUArray ty)] -> ChunkedUArray ty
    fromList = [ty] -> ChunkedUArray ty
    [Item (ChunkedUArray ty)] -> ChunkedUArray ty
    forall ty. PrimType ty => [ty] -> ChunkedUArray ty
    vFromList
        toList :: ChunkedUArray ty -> [Item (ChunkedUArray ty)]
    toList = ChunkedUArray ty -> [ty]
    ChunkedUArray ty -> [Item (ChunkedUArray ty)]
    forall ty. PrimType ty => ChunkedUArray ty -> [ty]
    vToList

    instance PrimType ty => C.Foldable (ChunkedUArray ty) where
        foldl' :: forall a.
    (a -> Element (ChunkedUArray ty) -> a)
    -> a -> ChunkedUArray ty -> a
    foldl' = (a -> ty -> a) -> a -> ChunkedUArray ty -> a
    (a -> Element (ChunkedUArray ty) -> a)
    -> a -> ChunkedUArray ty -> a
    forall ty a.
    PrimType ty =>
    (a -> ty -> a) -> a -> ChunkedUArray ty -> a
    foldl'
        foldr :: forall a.
    (Element (ChunkedUArray ty) -> a -> a)
    -> a -> ChunkedUArray ty -> a
    foldr = (ty -> a -> a) -> a -> ChunkedUArray ty -> a
    (Element (ChunkedUArray ty) -> a -> a)
    -> a -> ChunkedUArray ty -> a
    forall ty a.
    PrimType ty =>
    (ty -> a -> a) -> a -> ChunkedUArray ty -> a
    foldr
        -- Use the default foldr' instance

    instance PrimType ty => C.Collection (ChunkedUArray ty) where
        null :: ChunkedUArray ty -> Bool
    null = ChunkedUArray ty -> Bool
    forall ty. PrimType ty => ChunkedUArray ty -> Bool
    null
        length :: ChunkedUArray ty -> CountOf (Element (ChunkedUArray ty))
    length = ChunkedUArray ty -> CountOf ty
    ChunkedUArray ty -> CountOf (Element (ChunkedUArray ty))
    forall ty. PrimType ty => ChunkedUArray ty -> CountOf ty
    length
        elem :: forall a.
    (Eq a, a ~ Element (ChunkedUArray ty)) =>
    Element (ChunkedUArray ty) -> ChunkedUArray ty -> Bool
    elem   = ty -> ChunkedUArray ty -> Bool
    Element (ChunkedUArray ty) -> ChunkedUArray ty -> Bool
    forall ty. PrimType ty => ty -> ChunkedUArray ty -> Bool
    elem
        minimum :: forall a.
    (Ord a, a ~ Element (ChunkedUArray ty)) =>
    NonEmpty (ChunkedUArray ty) -> Element (ChunkedUArray ty)
    minimum = NonEmpty (ChunkedUArray ty) -> ty
    NonEmpty (ChunkedUArray ty) -> Element (ChunkedUArray ty)
    forall ty.
    (Ord ty, PrimType ty) =>
    NonEmpty (ChunkedUArray ty) -> ty
    minimum
        maximum :: forall a.
    (Ord a, a ~ Element (ChunkedUArray ty)) =>
    NonEmpty (ChunkedUArray ty) -> Element (ChunkedUArray ty)
    maximum = NonEmpty (ChunkedUArray ty) -> ty
    NonEmpty (ChunkedUArray ty) -> Element (ChunkedUArray ty)
    forall ty.
    (Ord ty, PrimType ty) =>
    NonEmpty (ChunkedUArray ty) -> ty
    maximum
        all :: (Element (ChunkedUArray ty) -> Bool) -> ChunkedUArray ty -> Bool
    all Element (ChunkedUArray ty) -> Bool
    p (ChunkedUArray Array (UArray ty)
    cua) = (UArray ty -> Bool) -> Array (UArray ty) -> Bool
    forall ty. (ty -> Bool) -> Array ty -> Bool
    A.all ((ty -> Bool) -> UArray ty -> Bool
    forall ty. PrimType ty => (ty -> Bool) -> UArray ty -> Bool
    U.all ty -> Bool
    Element (ChunkedUArray ty) -> Bool
    p) Array (UArray ty)
    cua
        any :: (Element (ChunkedUArray ty) -> Bool) -> ChunkedUArray ty -> Bool
    any Element (ChunkedUArray ty) -> Bool
    p (ChunkedUArray Array (UArray ty)
    cua) = (UArray ty -> Bool) -> Array (UArray ty) -> Bool
    forall ty. (ty -> Bool) -> Array ty -> Bool
    A.any ((ty -> Bool) -> UArray ty -> Bool
    forall ty. PrimType ty => (ty -> Bool) -> UArray ty -> Bool
    U.any ty -> Bool
    Element (ChunkedUArray ty) -> Bool
    p) Array (UArray ty)
    cua

    instance PrimType ty => C.Sequential (ChunkedUArray ty) where
        take :: CountOf (Element (ChunkedUArray ty))
    -> ChunkedUArray ty -> ChunkedUArray ty
    take = CountOf ty -> ChunkedUArray ty -> ChunkedUArray ty
    CountOf (Element (ChunkedUArray ty))
    -> ChunkedUArray ty -> ChunkedUArray ty
    forall ty.
    PrimType ty =>
    CountOf ty -> ChunkedUArray ty -> ChunkedUArray ty
    take
        drop :: CountOf (Element (ChunkedUArray ty))
    -> ChunkedUArray ty -> ChunkedUArray ty
    drop = CountOf ty -> ChunkedUArray ty -> ChunkedUArray ty
    CountOf (Element (ChunkedUArray ty))
    -> ChunkedUArray ty -> ChunkedUArray ty
    forall ty.
    PrimType ty =>
    CountOf ty -> ChunkedUArray ty -> ChunkedUArray ty
    drop
        splitAt :: CountOf (Element (ChunkedUArray ty))
    -> ChunkedUArray ty -> (ChunkedUArray ty, ChunkedUArray ty)
    splitAt = CountOf ty
    -> ChunkedUArray ty -> (ChunkedUArray ty, ChunkedUArray ty)
    CountOf (Element (ChunkedUArray ty))
    -> ChunkedUArray ty -> (ChunkedUArray ty, ChunkedUArray ty)
    forall ty.
    PrimType ty =>
    CountOf ty
    -> ChunkedUArray ty -> (ChunkedUArray ty, ChunkedUArray ty)
    splitAt
        revTake :: CountOf (Element (ChunkedUArray ty))
    -> ChunkedUArray ty -> ChunkedUArray ty
    revTake = CountOf ty -> ChunkedUArray ty -> ChunkedUArray ty
    CountOf (Element (ChunkedUArray ty))
    -> ChunkedUArray ty -> ChunkedUArray ty
    forall ty.
    PrimType ty =>
    CountOf ty -> ChunkedUArray ty -> ChunkedUArray ty
    revTake
        revDrop :: CountOf (Element (ChunkedUArray ty))
    -> ChunkedUArray ty -> ChunkedUArray ty
    revDrop = CountOf ty -> ChunkedUArray ty -> ChunkedUArray ty
    CountOf (Element (ChunkedUArray ty))
    -> ChunkedUArray ty -> ChunkedUArray ty
    forall ty.
    PrimType ty =>
    CountOf ty -> ChunkedUArray ty -> ChunkedUArray ty
    revDrop
        splitOn :: (Element (ChunkedUArray ty) -> Bool)
    -> ChunkedUArray ty -> [ChunkedUArray ty]
    splitOn = (ty -> Bool) -> ChunkedUArray ty -> [ChunkedUArray ty]
    (Element (ChunkedUArray ty) -> Bool)
    -> ChunkedUArray ty -> [ChunkedUArray ty]
    forall ty.
    PrimType ty =>
    (ty -> Bool) -> ChunkedUArray ty -> [ChunkedUArray ty]
    splitOn
        break :: (Element (ChunkedUArray ty) -> Bool)
    -> ChunkedUArray ty -> (ChunkedUArray ty, ChunkedUArray ty)
    break = (ty -> Bool)
    -> ChunkedUArray ty -> (ChunkedUArray ty, ChunkedUArray ty)
    (Element (ChunkedUArray ty) -> Bool)
    -> ChunkedUArray ty -> (ChunkedUArray ty, ChunkedUArray ty)
    forall ty.
    PrimType ty =>
    (ty -> Bool)
    -> ChunkedUArray ty -> (ChunkedUArray ty, ChunkedUArray ty)
    break
        breakEnd :: (Element (ChunkedUArray ty) -> Bool)
    -> ChunkedUArray ty -> (ChunkedUArray ty, ChunkedUArray ty)
    breakEnd = (ty -> Bool)
    -> ChunkedUArray ty -> (ChunkedUArray ty, ChunkedUArray ty)
    (Element (ChunkedUArray ty) -> Bool)
    -> ChunkedUArray ty -> (ChunkedUArray ty, ChunkedUArray ty)
    forall ty.
    PrimType ty =>
    (ty -> Bool)
    -> ChunkedUArray ty -> (ChunkedUArray ty, ChunkedUArray ty)
    breakEnd
        intersperse :: Element (ChunkedUArray ty) -> ChunkedUArray ty -> ChunkedUArray ty
    intersperse = ty -> ChunkedUArray ty -> ChunkedUArray ty
    Element (ChunkedUArray ty) -> ChunkedUArray ty -> ChunkedUArray ty
    forall ty.
    PrimType ty =>
    ty -> ChunkedUArray ty -> ChunkedUArray ty
    intersperse
        filter :: (Element (ChunkedUArray ty) -> Bool)
    -> ChunkedUArray ty -> ChunkedUArray ty
    filter = (ty -> Bool) -> ChunkedUArray ty -> ChunkedUArray ty
    (Element (ChunkedUArray ty) -> Bool)
    -> ChunkedUArray ty -> ChunkedUArray ty
    forall ty.
    PrimType ty =>
    (ty -> Bool) -> ChunkedUArray ty -> ChunkedUArray ty
    filter
        reverse :: ChunkedUArray ty -> ChunkedUArray ty
    reverse = ChunkedUArray ty -> ChunkedUArray ty
    forall ty. PrimType ty => ChunkedUArray ty -> ChunkedUArray ty
    reverse
        unsnoc :: ChunkedUArray ty
    -> Maybe (ChunkedUArray ty, Element (ChunkedUArray ty))
    unsnoc = ChunkedUArray ty -> Maybe (ChunkedUArray ty, ty)
    ChunkedUArray ty
    -> Maybe (ChunkedUArray ty, Element (ChunkedUArray ty))
    forall ty.
    PrimType ty =>
    ChunkedUArray ty -> Maybe (ChunkedUArray ty, ty)
    unsnoc
        uncons :: ChunkedUArray ty
    -> Maybe (Element (ChunkedUArray ty), ChunkedUArray ty)
    uncons = ChunkedUArray ty -> Maybe (ty, ChunkedUArray ty)
    ChunkedUArray ty
    -> Maybe (Element (ChunkedUArray ty), ChunkedUArray ty)
    forall ty.
    PrimType ty =>
    ChunkedUArray ty -> Maybe (ty, ChunkedUArray ty)
    uncons
        snoc :: ChunkedUArray ty -> Element (ChunkedUArray ty) -> ChunkedUArray ty
    snoc = ChunkedUArray ty -> ty -> ChunkedUArray ty
    ChunkedUArray ty -> Element (ChunkedUArray ty) -> ChunkedUArray ty
    forall ty.
    PrimType ty =>
    ChunkedUArray ty -> ty -> ChunkedUArray ty
    snoc
        cons :: Element (ChunkedUArray ty) -> ChunkedUArray ty -> ChunkedUArray ty
    cons = ty -> ChunkedUArray ty -> ChunkedUArray ty
    Element (ChunkedUArray ty) -> ChunkedUArray ty -> ChunkedUArray ty
    forall ty.
    PrimType ty =>
    ty -> ChunkedUArray ty -> ChunkedUArray ty
    cons
        find :: (Element (ChunkedUArray ty) -> Bool)
    -> ChunkedUArray ty -> Maybe (Element (ChunkedUArray ty))
    find = (ty -> Bool) -> ChunkedUArray ty -> Maybe ty
    (Element (ChunkedUArray ty) -> Bool)
    -> ChunkedUArray ty -> Maybe (Element (ChunkedUArray ty))
    forall ty.
    PrimType ty =>
    (ty -> Bool) -> ChunkedUArray ty -> Maybe ty
    find
        sortBy :: (Element (ChunkedUArray ty)
     -> Element (ChunkedUArray ty) -> Ordering)
    -> ChunkedUArray ty -> ChunkedUArray ty
    sortBy = (ty -> ty -> Ordering) -> ChunkedUArray ty -> ChunkedUArray ty
    (Element (ChunkedUArray ty)
     -> Element (ChunkedUArray ty) -> Ordering)
    -> ChunkedUArray ty -> ChunkedUArray ty
    forall ty.
    PrimType ty =>
    (ty -> ty -> Ordering) -> ChunkedUArray ty -> ChunkedUArray ty
    sortBy
        singleton :: Element (ChunkedUArray ty) -> ChunkedUArray ty
    singleton = [ty] -> ChunkedUArray ty
    [Item (ChunkedUArray ty)] -> ChunkedUArray ty
    forall l. IsList l => [Item l] -> l
    fromList ([ty] -> ChunkedUArray ty)
    -> (ty -> [ty]) -> ty -> ChunkedUArray ty
    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
    . (ty -> [ty] -> [ty]
    forall a. a -> [a] -> [a]
    :[])
        replicate :: CountOf (Element (ChunkedUArray ty))
    -> Element (ChunkedUArray ty) -> ChunkedUArray ty
    replicate CountOf (Element (ChunkedUArray ty))
    n = [ty] -> ChunkedUArray ty
    [Item (ChunkedUArray ty)] -> ChunkedUArray ty
    forall l. IsList l => [Item l] -> l
    fromList ([ty] -> ChunkedUArray ty)
    -> (ty -> [ty]) -> ty -> ChunkedUArray ty
    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
    . CountOf (Element [ty]) -> Element [ty] -> [ty]
    forall c. Sequential c => CountOf (Element c) -> Element c -> c
    C.replicate CountOf (Element [ty])
    CountOf (Element (ChunkedUArray ty))
    n

    instance PrimType ty => C.IndexedCollection (ChunkedUArray ty) where
        ! :: ChunkedUArray ty
    -> Offset (Element (ChunkedUArray ty))
    -> Maybe (Element (ChunkedUArray ty))
    (!) ChunkedUArray ty
    l Offset (Element (ChunkedUArray ty))
    n
            | Offset ty -> CountOf ty -> Bool
    forall ty. Offset ty -> CountOf ty -> Bool
    isOutOfBound Offset ty
    Offset (Element (ChunkedUArray ty))
    n (ChunkedUArray ty -> CountOf ty
    forall ty. PrimType ty => ChunkedUArray ty -> CountOf ty
    length ChunkedUArray ty
    l) = Maybe ty
    Maybe (Element (ChunkedUArray ty))
    forall a. Maybe a
    Nothing
            | Bool
    otherwise                     = Element (ChunkedUArray ty) -> Maybe (Element (ChunkedUArray ty))
    forall a. a -> Maybe a
    Just (Element (ChunkedUArray ty) -> Maybe (Element (ChunkedUArray ty)))
    -> Element (ChunkedUArray ty) -> Maybe (Element (ChunkedUArray ty))
    forall a b. (a -> b) -> a -> b
    $ ChunkedUArray ty -> Offset ty -> ty
    forall ty. PrimType ty => ChunkedUArray ty -> Offset ty -> ty
    index ChunkedUArray ty
    l Offset ty
    Offset (Element (ChunkedUArray ty))
    n
        findIndex :: (Element (ChunkedUArray ty) -> Bool)
    -> ChunkedUArray ty -> Maybe (Offset (Element (ChunkedUArray ty)))
    findIndex Element (ChunkedUArray ty) -> Bool
    predicate ChunkedUArray ty
    c = Offset ty -> Maybe (Offset ty)
    loop Offset ty
    0
          where
            !len :: CountOf ty
    len = ChunkedUArray ty -> CountOf ty
    forall ty. PrimType ty => ChunkedUArray ty -> CountOf ty
    length ChunkedUArray ty
    c
            loop :: Offset ty -> Maybe (Offset ty)
    loop Offset ty
    i
                | Offset ty
    i Offset ty -> CountOf ty -> Bool
    forall ty. Offset ty -> CountOf ty -> Bool
    .==# CountOf ty
    len = Maybe (Offset ty)
    forall a. Maybe a
    Nothing
                | Bool
    otherwise  =
                    if Element (ChunkedUArray ty) -> Bool
    predicate (ChunkedUArray ty -> Offset ty -> ty
    forall ty. PrimType ty => ChunkedUArray ty -> Offset ty -> ty
    unsafeIndex ChunkedUArray ty
    c Offset ty
    i) then Offset ty -> Maybe (Offset ty)
    forall a. a -> Maybe a
    Just Offset ty
    i else Maybe (Offset ty)
    forall a. Maybe a
    Nothing

    empty :: ChunkedUArray ty
    empty :: forall a. ChunkedUArray a
    empty = Array (UArray ty) -> ChunkedUArray ty
    forall ty. Array (UArray ty) -> ChunkedUArray ty
    ChunkedUArray Array (UArray ty)
    forall a. Array a
    A.empty

    append :: ChunkedUArray ty -> ChunkedUArray ty -> ChunkedUArray ty
    append :: forall a. ChunkedUArray a -> ChunkedUArray a -> ChunkedUArray a
    append (ChunkedUArray Array (UArray ty)
    a1) (ChunkedUArray Array (UArray ty)
    a2) = Array (UArray ty) -> ChunkedUArray ty
    forall ty. Array (UArray ty) -> ChunkedUArray ty
    ChunkedUArray (Array (UArray ty) -> Array (UArray ty) -> Array (UArray ty)
    forall a. Monoid a => a -> a -> a
    mappend Array (UArray ty)
    a1 Array (UArray ty)
    a2)

    concat :: [ChunkedUArray ty] -> ChunkedUArray ty
    concat :: forall a. [ChunkedUArray a] -> ChunkedUArray a
    concat [ChunkedUArray ty]
    x = Array (UArray ty) -> ChunkedUArray ty
    forall ty. Array (UArray ty) -> ChunkedUArray ty
    ChunkedUArray ([Array (UArray ty)] -> Array (UArray ty)
    forall a. Monoid a => [a] -> a
    mconcat ([Array (UArray ty)] -> Array (UArray ty))
    -> [Array (UArray ty)] -> Array (UArray ty)
    forall a b. (a -> b) -> a -> b
    $ (ChunkedUArray ty -> Array (UArray ty))
    -> [ChunkedUArray ty] -> [Array (UArray ty)]
    forall a b. (a -> b) -> [a] -> [b]
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap (\(ChunkedUArray Array (UArray ty)
    spine) -> Array (UArray ty)
    spine) [ChunkedUArray ty]
    x)

    vFromList :: PrimType ty => [ty] -> ChunkedUArray ty
    vFromList :: forall ty. PrimType ty => [ty] -> ChunkedUArray ty
    vFromList [ty]
    l = Array (UArray ty) -> ChunkedUArray ty
    forall ty. Array (UArray ty) -> ChunkedUArray ty
    ChunkedUArray (Array (UArray ty) -> ChunkedUArray ty)
    -> Array (UArray ty) -> ChunkedUArray ty
    forall a b. (a -> b) -> a -> b
    $ UArray ty -> Array (UArray ty)
    forall ty. ty -> Array ty
    A.singleton (UArray ty -> Array (UArray ty)) -> UArray ty -> Array (UArray ty)
    forall a b. (a -> b) -> a -> b
    $ [Item (UArray ty)] -> UArray ty
    forall l. IsList l => [Item l] -> l
    fromList [ty]
    [Item (UArray ty)]
    l

    vToList :: PrimType ty => ChunkedUArray ty -> [ty]
    vToList :: forall ty. PrimType ty => ChunkedUArray ty -> [ty]
    vToList (ChunkedUArray Array (UArray ty)
    a) = [[ty]] -> [ty]
    forall a. Monoid a => [a] -> a
    mconcat ([[ty]] -> [ty]) -> [[ty]] -> [ty]
    forall a b. (a -> b) -> a -> b
    $ Array [ty] -> [Item (Array [ty])]
    forall l. IsList l => l -> [Item l]
    toList (Array [ty] -> [Item (Array [ty])])
    -> Array [ty] -> [Item (Array [ty])]
    forall a b. (a -> b) -> a -> b
    $ UArray ty -> [ty]
    UArray ty -> [Item (UArray ty)]
    forall l. IsList l => l -> [Item l]
    toList (UArray ty -> [ty]) -> Array (UArray ty) -> Array [ty]
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Array (UArray ty)
    a

    null :: PrimType ty => ChunkedUArray ty -> Bool
    null :: forall ty. PrimType ty => ChunkedUArray ty -> Bool
    null (ChunkedUArray Array (UArray ty)
    array) =
        Array (UArray ty) -> Bool
    forall c. Collection c => c -> Bool
    C.null Array (UArray ty)
    array Bool -> Bool -> Bool
    || Offset (UArray ty) -> Bool
    allNulls Offset (UArray ty)
    0
      where
        !len :: CountOf (UArray ty)
    len = Array (UArray ty) -> CountOf (UArray ty)
    forall a. Array a -> CountOf a
    A.length Array (UArray ty)
    array
        allNulls :: Offset (UArray ty) -> Bool
    allNulls !Offset (UArray ty)
    idx
          | Offset (UArray ty)
    idx Offset (UArray ty) -> CountOf (UArray ty) -> Bool
    forall ty. Offset ty -> CountOf ty -> Bool
    .==# CountOf (UArray ty)
    len = Bool
    True
          | Bool
    otherwise    = UArray ty -> Bool
    forall c. Collection c => c -> Bool
    C.null (Array (UArray ty)
    array Array (UArray ty) -> Offset (UArray ty) -> UArray ty
    forall ty. Array ty -> Offset ty -> ty
    `A.unsafeIndex` Offset (UArray ty)
    idx) Bool -> Bool -> Bool
    && Offset (UArray ty) -> Bool
    allNulls (Offset (UArray ty)
    idx Offset (UArray ty) -> Offset (UArray ty) -> Offset (UArray ty)
    forall a. Additive a => a -> a -> a
    + Offset (UArray ty)
    1)

    -- | Returns the length of this `ChunkedUArray`, by summing each inner length.
    -- Complexity: O(n) where `n` is the number of chunks, as U.length u is O(1).
    length :: PrimType ty => ChunkedUArray ty -> CountOf ty
    length :: forall ty. PrimType ty => ChunkedUArray ty -> CountOf ty
    length (ChunkedUArray Array (UArray ty)
    array) = (CountOf ty -> Element (Array (UArray ty)) -> CountOf ty)
    -> CountOf ty -> Array (UArray ty) -> CountOf ty
    forall collection a.
    Foldable collection =>
    (a -> Element collection -> a) -> a -> collection -> a
    forall a.
    (a -> Element (Array (UArray ty)) -> a)
    -> a -> Array (UArray ty) -> a
    C.foldl' (\CountOf ty
    acc Element (Array (UArray ty))
    l -> CountOf ty
    acc CountOf ty -> CountOf ty -> CountOf ty
    forall a. Additive a => a -> a -> a
    + UArray ty -> CountOf ty
    forall ty. UArray ty -> CountOf ty
    U.length UArray ty
    Element (Array (UArray ty))
    l) CountOf ty
    0 Array (UArray ty)
    array

    -- | Returns `True` if the given element is contained in the `ChunkedUArray`.
    -- Complexity: O(n) where `n` is the number of chunks, as U.length u is O(1).
    elem :: PrimType ty => ty -> ChunkedUArray ty -> Bool
    elem :: forall ty. PrimType ty => ty -> ChunkedUArray ty -> Bool
    elem ty
    el (ChunkedUArray Array (UArray ty)
    array) = Offset (UArray ty) -> Bool
    loop Offset (UArray ty)
    0
      where
        !len :: CountOf (UArray ty)
    len = Array (UArray ty) -> CountOf (UArray ty)
    forall a. Array a -> CountOf a
    A.length Array (UArray ty)
    array
        loop :: Offset (UArray ty) -> Bool
    loop Offset (UArray ty)
    i
            | Offset (UArray ty)
    i Offset (UArray ty) -> CountOf (UArray ty) -> Bool
    forall ty. Offset ty -> CountOf ty -> Bool
    .==# CountOf (UArray ty)
    len = Bool
    False
            | Bool
    otherwise  =
                case Element (UArray ty) -> UArray ty -> Bool
    forall a.
    (Eq a, a ~ Element (UArray ty)) =>
    Element (UArray ty) -> UArray ty -> Bool
    forall c a.
    (Collection c, Eq a, a ~ Element c) =>
    Element c -> c -> Bool
    C.elem ty
    Element (UArray ty)
    el (Array (UArray ty) -> Offset (UArray ty) -> UArray ty
    forall ty. Array ty -> Offset ty -> ty
    A.unsafeIndex Array (UArray ty)
    array Offset (UArray ty)
    i) of
                    Bool
    True  -> Bool
    True
                    Bool
    False -> Offset (UArray ty) -> Bool
    loop (Offset (UArray ty)
    iOffset (UArray ty) -> Offset (UArray ty) -> Offset (UArray ty)
    forall a. Additive a => a -> a -> a
    +Offset (UArray ty)
    1)

    -- | Fold a `ChunkedUArray' leftwards strictly. Implemented internally using a double
    -- fold on the nested Array structure. Other folds implemented analogously.
    foldl' :: PrimType ty => (a -> ty -> a) -> a -> ChunkedUArray ty -> a
    foldl' :: forall ty a.
    PrimType ty =>
    (a -> ty -> a) -> a -> ChunkedUArray ty -> a
    foldl' a -> ty -> a
    f a
    initialAcc (ChunkedUArray Array (UArray ty)
    cua) = (a -> UArray ty -> a) -> a -> Array (UArray ty) -> a
    forall a ty. (a -> ty -> a) -> a -> Array ty -> a
    A.foldl' ((a -> ty -> a) -> a -> UArray ty -> a
    forall ty a. PrimType ty => (a -> ty -> a) -> a -> UArray ty -> a
    U.foldl' a -> ty -> a
    f) a
    initialAcc Array (UArray ty)
    cua

    foldr :: PrimType ty => (ty -> a -> a) -> a -> ChunkedUArray ty -> a
    foldr :: forall ty a.
    PrimType ty =>
    (ty -> a -> a) -> a -> ChunkedUArray ty -> a
    foldr ty -> a -> a
    f a
    initialAcc (ChunkedUArray Array (UArray ty)
    cua) = (UArray ty -> a -> a) -> a -> Array (UArray ty) -> a
    forall ty a. (ty -> a -> a) -> a -> Array ty -> a
    A.foldr ((a -> UArray ty -> a) -> UArray ty -> a -> a
    forall a b c. (a -> b -> c) -> b -> a -> c
    flip ((a -> UArray ty -> a) -> UArray ty -> a -> a)
    -> (a -> UArray ty -> a) -> UArray ty -> a -> a
    forall a b. (a -> b) -> a -> b
    $ (ty -> a -> a) -> a -> UArray ty -> a
    forall ty a. PrimType ty => (ty -> a -> a) -> a -> UArray ty -> a
    U.foldr ty -> a -> a
    f) a
    initialAcc Array (UArray ty)
    cua

    minimum :: (Ord ty, PrimType ty) => C.NonEmpty (ChunkedUArray ty) -> ty
    minimum :: forall ty.
    (Ord ty, PrimType ty) =>
    NonEmpty (ChunkedUArray ty) -> ty
    minimum NonEmpty (ChunkedUArray ty)
    cua = (ty -> ty -> ty) -> ty -> ChunkedUArray ty -> ty
    forall ty a.
    PrimType ty =>
    (a -> ty -> a) -> a -> ChunkedUArray ty -> a
    foldl' ty -> ty -> ty
    forall a. Ord a => a -> a -> a
    min (ChunkedUArray ty -> Offset ty -> ty
    forall ty. PrimType ty => ChunkedUArray ty -> Offset ty -> ty
    unsafeIndex ChunkedUArray ty
    cua' Offset ty
    0) (CountOf ty -> ChunkedUArray ty -> ChunkedUArray ty
    forall ty.
    PrimType ty =>
    CountOf ty -> ChunkedUArray ty -> ChunkedUArray ty
    drop CountOf ty
    1 ChunkedUArray ty
    cua')
      where
        cua' :: ChunkedUArray ty
    cua' = NonEmpty (ChunkedUArray ty) -> ChunkedUArray ty
    forall a. NonEmpty a -> a
    C.getNonEmpty NonEmpty (ChunkedUArray ty)
    cua

    maximum :: (Ord ty, PrimType ty) => C.NonEmpty (ChunkedUArray ty) -> ty
    maximum :: forall ty.
    (Ord ty, PrimType ty) =>
    NonEmpty (ChunkedUArray ty) -> ty
    maximum NonEmpty (ChunkedUArray ty)
    cua = (ty -> ty -> ty) -> ty -> ChunkedUArray ty -> ty
    forall ty a.
    PrimType ty =>
    (a -> ty -> a) -> a -> ChunkedUArray ty -> a
    foldl' ty -> ty -> ty
    forall a. Ord a => a -> a -> a
    max (ChunkedUArray ty -> Offset ty -> ty
    forall ty. PrimType ty => ChunkedUArray ty -> Offset ty -> ty
    unsafeIndex ChunkedUArray ty
    cua' Offset ty
    0) (CountOf ty -> ChunkedUArray ty -> ChunkedUArray ty
    forall ty.
    PrimType ty =>
    CountOf ty -> ChunkedUArray ty -> ChunkedUArray ty
    drop CountOf ty
    1 ChunkedUArray ty
    cua')
      where
        cua' :: ChunkedUArray ty
    cua' = NonEmpty (ChunkedUArray ty) -> ChunkedUArray ty
    forall a. NonEmpty a -> a
    C.getNonEmpty NonEmpty (ChunkedUArray ty)
    cua

    -- | Equality between `ChunkedUArray`.
    -- This function is fiddly to write as is not enough to compare for
    -- equality the inner `UArray`(s), we need an element-by-element
    -- comparison.
    equal :: PrimType ty => ChunkedUArray ty -> ChunkedUArray ty -> Bool
    equal :: forall ty.
    PrimType ty =>
    ChunkedUArray ty -> ChunkedUArray ty -> Bool
    equal ChunkedUArray ty
    ca1 ChunkedUArray ty
    ca2 =
        CountOf ty
    len1 CountOf ty -> CountOf ty -> Bool
    forall a. Eq a => a -> a -> Bool
    == CountOf ty
    len2 Bool -> Bool -> Bool
    && Offset ty -> Bool
    go Offset ty
    0
      where
        len1 :: CountOf ty
    len1 = ChunkedUArray ty -> CountOf ty
    forall ty. PrimType ty => ChunkedUArray ty -> CountOf ty
    length ChunkedUArray ty
    ca1
        len2 :: CountOf ty
    len2 = ChunkedUArray ty -> CountOf ty
    forall ty. PrimType ty => ChunkedUArray ty -> CountOf ty
    length ChunkedUArray ty
    ca2

        go :: Offset ty -> Bool
    go !Offset ty
    x
          | Offset ty
    x Offset ty -> CountOf ty -> Bool
    forall ty. Offset ty -> CountOf ty -> Bool
    .==# CountOf ty
    len1 = Bool
    True
          | Bool
    otherwise   = (ChunkedUArray ty
    ca1 ChunkedUArray ty -> Offset ty -> ty
    forall ty. PrimType ty => ChunkedUArray ty -> Offset ty -> ty
    `unsafeIndex` Offset ty
    x ty -> ty -> Bool
    forall a. Eq a => a -> a -> Bool
    == ChunkedUArray ty
    ca2 ChunkedUArray ty -> Offset ty -> ty
    forall ty. PrimType ty => ChunkedUArray ty -> Offset ty -> ty
    `unsafeIndex` Offset ty
    x) Bool -> Bool -> Bool
    && Offset ty -> Bool
    go (Offset ty
    x Offset ty -> Offset ty -> Offset ty
    forall a. Additive a => a -> a -> a
    + Offset ty
    1)

    -- given an offset express in element of ty, return the offset in array in the spine,
    -- plus the relative offset in element on this array
    findPos :: PrimType ty => Offset ty -> ChunkedUArray ty -> Maybe (Offset (UArray ty), Offset ty)
    findPos :: forall ty.
    PrimType ty =>
    Offset ty
    -> ChunkedUArray ty -> Maybe (Offset (UArray ty), Offset ty)
    findPos Offset ty
    absOfs (ChunkedUArray Array (UArray ty)
    array)
        | Array (UArray ty) -> Bool
    forall ty. Array ty -> Bool
    A.null Array (UArray ty)
    array = Maybe (Offset (UArray ty), Offset ty)
    forall a. Maybe a
    Nothing
        | Bool
    otherwise    = Offset ty
    -> Offset (UArray ty) -> Maybe (Offset (UArray ty), Offset ty)
    loop Offset ty
    absOfs Offset (UArray ty)
    0
      where
        !len :: CountOf (UArray ty)
    len = Array (UArray ty) -> CountOf (UArray ty)
    forall a. Array a -> CountOf a
    A.length Array (UArray ty)
    array
        loop :: Offset ty
    -> Offset (UArray ty) -> Maybe (Offset (UArray ty), Offset ty)
    loop Offset ty
    relOfs Offset (UArray ty)
    outerI
            | Offset (UArray ty)
    outerI Offset (UArray ty) -> CountOf (UArray ty) -> Bool
    forall ty. Offset ty -> CountOf ty -> Bool
    .==# CountOf (UArray ty)
    len = Maybe (Offset (UArray ty), Offset ty)
    forall a. Maybe a
    Nothing -- haven't found what to do
            | Offset ty
    relOfs Offset ty -> Offset ty -> Bool
    forall a. Eq a => a -> a -> Bool
    == Offset ty
    0     = (Offset (UArray ty), Offset ty)
    -> Maybe (Offset (UArray ty), Offset ty)
    forall a. a -> Maybe a
    Just (Offset (UArray ty)
    outerI, Offset ty
    0)
            | Bool
    otherwise       =
                let !innera :: UArray ty
    innera   = Array (UArray ty) -> Offset (UArray ty) -> UArray ty
    forall ty. Array ty -> Offset ty -> ty
    A.unsafeIndex Array (UArray ty)
    array Offset (UArray ty)
    outerI
                    !innerLen :: CountOf ty
    innerLen = UArray ty -> CountOf ty
    forall ty. UArray ty -> CountOf ty
    U.length UArray ty
    innera
                 in case Offset ty -> CountOf ty -> Maybe (Offset ty)
    forall ty. Offset ty -> CountOf ty -> Maybe (Offset ty)
    removeArraySize Offset ty
    relOfs CountOf ty
    innerLen of
                            Maybe (Offset ty)
    Nothing      -> (Offset (UArray ty), Offset ty)
    -> Maybe (Offset (UArray ty), Offset ty)
    forall a. a -> Maybe a
    Just (Offset (UArray ty)
    outerI, Offset ty
    relOfs)
                            Just Offset ty
    relOfs' -> Offset ty
    -> Offset (UArray ty) -> Maybe (Offset (UArray ty), Offset ty)
    loop Offset ty
    relOfs' (Offset (UArray ty)
    outerI Offset (UArray ty) -> Offset (UArray ty) -> Offset (UArray ty)
    forall a. Additive a => a -> a -> a
    + Offset (UArray ty)
    1)

    splitChunk :: Offset (UArray ty) -> ChunkedUArray ty -> (ChunkedUArray ty, ChunkedUArray ty)
    splitChunk :: forall ty.
    Offset (UArray ty)
    -> ChunkedUArray ty -> (ChunkedUArray ty, ChunkedUArray ty)
    splitChunk Offset (UArray ty)
    ofs (ChunkedUArray Array (UArray ty)
    c) = (Array (UArray ty) -> ChunkedUArray ty
    forall ty. Array (UArray ty) -> ChunkedUArray ty
    ChunkedUArray (Array (UArray ty) -> ChunkedUArray ty)
    -> (Array (UArray ty) -> ChunkedUArray ty)
    -> (Array (UArray ty), Array (UArray ty))
    -> (ChunkedUArray ty, ChunkedUArray ty)
    forall b c b' c'. (b -> c) -> (b' -> c') -> (b, b') -> (c, c')
    forall (a :: * -> * -> *) b c b' c'.
    Arrow a =>
    a b c -> a b' c' -> a (b, b') (c, c')
    *** Array (UArray ty) -> ChunkedUArray ty
    forall ty. Array (UArray ty) -> ChunkedUArray ty
    ChunkedUArray) ((Array (UArray ty), Array (UArray ty))
     -> (ChunkedUArray ty, ChunkedUArray ty))
    -> (Array (UArray ty), Array (UArray ty))
    -> (ChunkedUArray ty, ChunkedUArray ty)
    forall a b. (a -> b) -> a -> b
    $ CountOf (UArray ty)
    -> Array (UArray ty) -> (Array (UArray ty), Array (UArray ty))
    forall ty. CountOf ty -> Array ty -> (Array ty, Array ty)
    A.splitAt (Offset (UArray ty) -> CountOf (UArray ty)
    forall a. Offset a -> CountOf a
    offsetAsSize Offset (UArray ty)
    ofs) Array (UArray ty)
    c

    take :: PrimType ty => CountOf ty -> ChunkedUArray ty -> ChunkedUArray ty
    take :: forall ty.
    PrimType ty =>
    CountOf ty -> ChunkedUArray ty -> ChunkedUArray ty
    take CountOf ty
    n c :: ChunkedUArray ty
    c@(ChunkedUArray Array (UArray ty)
    spine)
        | CountOf ty
    n CountOf ty -> CountOf ty -> Bool
    forall a. Ord a => a -> a -> Bool
    <= CountOf ty
    0    = ChunkedUArray ty
    forall a. ChunkedUArray a
    empty
        | Bool
    otherwise =
            case Offset ty
    -> ChunkedUArray ty -> Maybe (Offset (UArray ty), Offset ty)
    forall ty.
    PrimType ty =>
    Offset ty
    -> ChunkedUArray ty -> Maybe (Offset (UArray ty), Offset ty)
    findPos (CountOf ty -> Offset ty
    forall a. CountOf a -> Offset a
    sizeAsOffset CountOf ty
    n) ChunkedUArray ty
    c of
                Maybe (Offset (UArray ty), Offset ty)
    Nothing       -> ChunkedUArray ty
    c
                Just (Offset (UArray ty)
    ofs, Offset ty
    0) -> Array (UArray ty) -> ChunkedUArray ty
    forall ty. Array (UArray ty) -> ChunkedUArray ty
    ChunkedUArray (CountOf (UArray ty) -> Array (UArray ty) -> Array (UArray ty)
    forall ty. CountOf ty -> Array ty -> Array ty
    A.take (Offset (UArray ty) -> CountOf (UArray ty)
    forall a. Offset a -> CountOf a
    offsetAsSize Offset (UArray ty)
    ofs) Array (UArray ty)
    spine)
                Just (Offset (UArray ty)
    ofs, Offset ty
    r) ->
                    let uarr :: UArray ty
    uarr = Array (UArray ty) -> Offset (UArray ty) -> UArray ty
    forall ty. Array ty -> Offset ty -> ty
    A.unsafeIndex Array (UArray ty)
    spine Offset (UArray ty)
    ofs
                     in Array (UArray ty) -> ChunkedUArray ty
    forall ty. Array (UArray ty) -> ChunkedUArray ty
    ChunkedUArray (CountOf (UArray ty) -> Array (UArray ty) -> Array (UArray ty)
    forall ty. CountOf ty -> Array ty -> Array ty
    A.take (Offset (UArray ty) -> CountOf (UArray ty)
    forall a. Offset a -> CountOf a
    offsetAsSize Offset (UArray ty)
    ofs) Array (UArray ty)
    spine Array (UArray ty) -> UArray ty -> Array (UArray ty)
    forall ty. Array ty -> ty -> Array ty
    `A.snoc` CountOf ty -> UArray ty -> UArray ty
    forall ty. CountOf ty -> UArray ty -> UArray ty
    U.take (Offset ty -> CountOf ty
    forall a. Offset a -> CountOf a
    offsetAsSize Offset ty
    r) UArray ty
    uarr)

    drop :: PrimType ty => CountOf ty -> ChunkedUArray ty -> ChunkedUArray ty
    drop :: forall ty.
    PrimType ty =>
    CountOf ty -> ChunkedUArray ty -> ChunkedUArray ty
    drop CountOf ty
    n c :: ChunkedUArray ty
    c@(ChunkedUArray Array (UArray ty)
    spine)
        | CountOf ty
    n CountOf ty -> CountOf ty -> Bool
    forall a. Ord a => a -> a -> Bool
    <= CountOf ty
    0    = ChunkedUArray ty
    c
        | Bool
    otherwise =
            case Offset ty
    -> ChunkedUArray ty -> Maybe (Offset (UArray ty), Offset ty)
    forall ty.
    PrimType ty =>
    Offset ty
    -> ChunkedUArray ty -> Maybe (Offset (UArray ty), Offset ty)
    findPos (CountOf ty -> Offset ty
    forall a. CountOf a -> Offset a
    sizeAsOffset CountOf ty
    n) ChunkedUArray ty
    c of
                Maybe (Offset (UArray ty), Offset ty)
    Nothing       -> ChunkedUArray ty
    forall a. ChunkedUArray a
    empty
                Just (Offset (UArray ty)
    ofs, Offset ty
    0) -> Array (UArray ty) -> ChunkedUArray ty
    forall ty. Array (UArray ty) -> ChunkedUArray ty
    ChunkedUArray (CountOf (UArray ty) -> Array (UArray ty) -> Array (UArray ty)
    forall ty. CountOf ty -> Array ty -> Array ty
    A.drop (Offset (UArray ty) -> CountOf (UArray ty)
    forall a. Offset a -> CountOf a
    offsetAsSize Offset (UArray ty)
    ofs) Array (UArray ty)
    spine)
                Just (Offset (UArray ty)
    ofs, Offset ty
    r) ->
                    let uarr :: UArray ty
    uarr = Array (UArray ty) -> Offset (UArray ty) -> UArray ty
    forall ty. Array ty -> Offset ty -> ty
    A.unsafeIndex Array (UArray ty)
    spine Offset (UArray ty)
    ofs
                     in Array (UArray ty) -> ChunkedUArray ty
    forall ty. Array (UArray ty) -> ChunkedUArray ty
    ChunkedUArray (CountOf ty -> UArray ty -> UArray ty
    forall ty. CountOf ty -> UArray ty -> UArray ty
    U.drop (Offset ty -> CountOf ty
    forall a. Offset a -> CountOf a
    offsetAsSize Offset ty
    r) UArray ty
    uarr UArray ty -> Array (UArray ty) -> Array (UArray ty)
    forall ty. ty -> Array ty -> Array ty
    `A.cons` CountOf (UArray ty) -> Array (UArray ty) -> Array (UArray ty)
    forall ty. CountOf ty -> Array ty -> Array ty
    A.drop (Offset (UArray ty) -> CountOf (UArray ty)
    forall a. Offset a -> CountOf a
    offsetAsSize Offset (UArray ty)
    ofsCountOf (UArray ty) -> CountOf (UArray ty) -> CountOf (UArray ty)
    forall a. Additive a => a -> a -> a
    +CountOf (UArray ty)
    1) Array (UArray ty)
    spine)

    splitAt :: PrimType ty => CountOf ty -> ChunkedUArray ty -> (ChunkedUArray ty, ChunkedUArray ty)
    splitAt :: forall ty.
    PrimType ty =>
    CountOf ty
    -> ChunkedUArray ty -> (ChunkedUArray ty, ChunkedUArray ty)
    splitAt CountOf ty
    n c :: ChunkedUArray ty
    c@(ChunkedUArray Array (UArray ty)
    spine)
        | CountOf ty
    n CountOf ty -> CountOf ty -> Bool
    forall a. Ord a => a -> a -> Bool
    <= CountOf ty
    0    = (ChunkedUArray ty
    forall a. ChunkedUArray a
    empty, ChunkedUArray ty
    c)
        | Bool
    otherwise =
            case Offset ty
    -> ChunkedUArray ty -> Maybe (Offset (UArray ty), Offset ty)
    forall ty.
    PrimType ty =>
    Offset ty
    -> ChunkedUArray ty -> Maybe (Offset (UArray ty), Offset ty)
    findPos (CountOf ty -> Offset ty
    forall a. CountOf a -> Offset a
    sizeAsOffset CountOf ty
    n) ChunkedUArray ty
    c of
                Maybe (Offset (UArray ty), Offset ty)
    Nothing       -> (ChunkedUArray ty
    c, ChunkedUArray ty
    forall a. ChunkedUArray a
    empty)
                Just (Offset (UArray ty)
    ofs, Offset ty
    0) -> Offset (UArray ty)
    -> ChunkedUArray ty -> (ChunkedUArray ty, ChunkedUArray ty)
    forall ty.
    Offset (UArray ty)
    -> ChunkedUArray ty -> (ChunkedUArray ty, ChunkedUArray ty)
    splitChunk Offset (UArray ty)
    ofs ChunkedUArray ty
    c
                Just (Offset (UArray ty)
    ofs, Offset ty -> CountOf ty
    forall a. Offset a -> CountOf a
    offsetAsSize -> CountOf ty
    r) ->
                    let uarr :: UArray ty
    uarr = Array (UArray ty) -> Offset (UArray ty) -> UArray ty
    forall ty. Array ty -> Offset ty -> ty
    A.unsafeIndex Array (UArray ty)
    spine Offset (UArray ty)
    ofs
                     in ( Array (UArray ty) -> ChunkedUArray ty
    forall ty. Array (UArray ty) -> ChunkedUArray ty
    ChunkedUArray (CountOf (UArray ty) -> Array (UArray ty) -> Array (UArray ty)
    forall ty. CountOf ty -> Array ty -> Array ty
    A.take (Offset (UArray ty) -> CountOf (UArray ty)
    forall a. Offset a -> CountOf a
    offsetAsSize Offset (UArray ty)
    ofs) Array (UArray ty)
    spine Array (UArray ty) -> UArray ty -> Array (UArray ty)
    forall ty. Array ty -> ty -> Array ty
    `A.snoc` CountOf ty -> UArray ty -> UArray ty
    forall ty. CountOf ty -> UArray ty -> UArray ty
    U.take CountOf ty
    r UArray ty
    uarr)
                        , Array (UArray ty) -> ChunkedUArray ty
    forall ty. Array (UArray ty) -> ChunkedUArray ty
    ChunkedUArray (CountOf ty -> UArray ty -> UArray ty
    forall ty. CountOf ty -> UArray ty -> UArray ty
    U.drop CountOf ty
    r UArray ty
    uarr UArray ty -> Array (UArray ty) -> Array (UArray ty)
    forall ty. ty -> Array ty -> Array ty
    `A.cons` CountOf (UArray ty) -> Array (UArray ty) -> Array (UArray ty)
    forall ty. CountOf ty -> Array ty -> Array ty
    A.drop (Offset (UArray ty) -> CountOf (UArray ty)
    forall a. Offset a -> CountOf a
    offsetAsSize Offset (UArray ty)
    ofsCountOf (UArray ty) -> CountOf (UArray ty) -> CountOf (UArray ty)
    forall a. Additive a => a -> a -> a
    +CountOf (UArray ty)
    1) Array (UArray ty)
    spine)
                        )

    revTake :: PrimType ty => CountOf ty -> ChunkedUArray ty -> ChunkedUArray ty
    revTake :: forall ty.
    PrimType ty =>
    CountOf ty -> ChunkedUArray ty -> ChunkedUArray ty
    revTake CountOf ty
    n ChunkedUArray ty
    c = case ChunkedUArray ty -> CountOf ty
    forall ty. PrimType ty => ChunkedUArray ty -> CountOf ty
    length ChunkedUArray ty
    c CountOf ty -> CountOf ty -> Difference (CountOf ty)
    forall a. Subtractive a => a -> a -> Difference a
    - CountOf ty
    n of
        Maybe (CountOf ty)
    Difference (CountOf ty)
    Nothing -> ChunkedUArray ty
    c
        Just CountOf ty
    elems -> CountOf ty -> ChunkedUArray ty -> ChunkedUArray ty
    forall ty.
    PrimType ty =>
    CountOf ty -> ChunkedUArray ty -> ChunkedUArray ty
    drop CountOf ty
    elems ChunkedUArray ty
    c

    revDrop :: PrimType ty => CountOf ty -> ChunkedUArray ty -> ChunkedUArray ty
    revDrop :: forall ty.
    PrimType ty =>
    CountOf ty -> ChunkedUArray ty -> ChunkedUArray ty
    revDrop CountOf ty
    n ChunkedUArray ty
    c = case ChunkedUArray ty -> CountOf ty
    forall ty. PrimType ty => ChunkedUArray ty -> CountOf ty
    length ChunkedUArray ty
    c CountOf ty -> CountOf ty -> Difference (CountOf ty)
    forall a. Subtractive a => a -> a -> Difference a
    - CountOf ty
    n of
        Maybe (CountOf ty)
    Difference (CountOf ty)
    Nothing -> ChunkedUArray ty
    forall a. ChunkedUArray a
    empty
        Just CountOf ty
    keepElems -> CountOf ty -> ChunkedUArray ty -> ChunkedUArray ty
    forall ty.
    PrimType ty =>
    CountOf ty -> ChunkedUArray ty -> ChunkedUArray ty
    take CountOf ty
    keepElems ChunkedUArray ty
    c

    -- TODO: Improve implementation.
    splitOn :: PrimType ty => (ty -> Bool) -> ChunkedUArray ty -> [ChunkedUArray ty]
    splitOn :: forall ty.
    PrimType ty =>
    (ty -> Bool) -> ChunkedUArray ty -> [ChunkedUArray ty]
    splitOn ty -> Bool
    p = ([ty] -> ChunkedUArray ty) -> [[ty]] -> [ChunkedUArray ty]
    forall a b. (a -> b) -> [a] -> [b]
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap [ty] -> ChunkedUArray ty
    [Item (ChunkedUArray ty)] -> ChunkedUArray ty
    forall l. IsList l => [Item l] -> l
    fromList ([[ty]] -> [ChunkedUArray ty])
    -> (ChunkedUArray ty -> [[ty]])
    -> ChunkedUArray ty
    -> [ChunkedUArray ty]
    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
    . (Element [ty] -> Bool) -> [ty] -> [[ty]]
    forall c. Sequential c => (Element c -> Bool) -> c -> [c]
    C.splitOn ty -> Bool
    Element [ty] -> Bool
    p ([ty] -> [[ty]])
    -> (ChunkedUArray ty -> [ty]) -> ChunkedUArray ty -> [[ty]]
    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
    . ChunkedUArray ty -> [ty]
    ChunkedUArray ty -> [Item (ChunkedUArray ty)]
    forall l. IsList l => l -> [Item l]
    toList

    -- TODO: Improve implementation.
    break :: PrimType ty => (ty -> Bool) -> ChunkedUArray ty -> (ChunkedUArray ty, ChunkedUArray ty)
    break :: forall ty.
    PrimType ty =>
    (ty -> Bool)
    -> ChunkedUArray ty -> (ChunkedUArray ty, ChunkedUArray ty)
    break ty -> Bool
    p = ([ty] -> ChunkedUArray ty)
    -> ([ty] -> ChunkedUArray ty)
    -> ([ty], [ty])
    -> (ChunkedUArray ty, ChunkedUArray ty)
    forall b c b' c'. (b -> c) -> (b' -> c') -> (b, b') -> (c, c')
    forall (p :: * -> * -> *) a b c d.
    Bifunctor p =>
    (a -> b) -> (c -> d) -> p a c -> p b d
    bimap [ty] -> ChunkedUArray ty
    [Item (ChunkedUArray ty)] -> ChunkedUArray ty
    forall l. IsList l => [Item l] -> l
    fromList [ty] -> ChunkedUArray ty
    [Item (ChunkedUArray ty)] -> ChunkedUArray ty
    forall l. IsList l => [Item l] -> l
    fromList (([ty], [ty]) -> (ChunkedUArray ty, ChunkedUArray ty))
    -> (ChunkedUArray ty -> ([ty], [ty]))
    -> ChunkedUArray ty
    -> (ChunkedUArray ty, ChunkedUArray ty)
    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
    . (Element [ty] -> Bool) -> [ty] -> ([ty], [ty])
    forall c. Sequential c => (Element c -> Bool) -> c -> (c, c)
    C.break ty -> Bool
    Element [ty] -> Bool
    p ([ty] -> ([ty], [ty]))
    -> (ChunkedUArray ty -> [ty]) -> ChunkedUArray ty -> ([ty], [ty])
    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
    . ChunkedUArray ty -> [ty]
    ChunkedUArray ty -> [Item (ChunkedUArray ty)]
    forall l. IsList l => l -> [Item l]
    toList

    -- TODO: Improve implementation.
    breakEnd :: PrimType ty => (ty -> Bool) -> ChunkedUArray ty -> (ChunkedUArray ty, ChunkedUArray ty)
    breakEnd :: forall ty.
    PrimType ty =>
    (ty -> Bool)
    -> ChunkedUArray ty -> (ChunkedUArray ty, ChunkedUArray ty)
    breakEnd ty -> Bool
    p = ([ty] -> ChunkedUArray ty)
    -> ([ty] -> ChunkedUArray ty)
    -> ([ty], [ty])
    -> (ChunkedUArray ty, ChunkedUArray ty)
    forall b c b' c'. (b -> c) -> (b' -> c') -> (b, b') -> (c, c')
    forall (p :: * -> * -> *) a b c d.
    Bifunctor p =>
    (a -> b) -> (c -> d) -> p a c -> p b d
    bimap [ty] -> ChunkedUArray ty
    [Item (ChunkedUArray ty)] -> ChunkedUArray ty
    forall l. IsList l => [Item l] -> l
    fromList [ty] -> ChunkedUArray ty
    [Item (ChunkedUArray ty)] -> ChunkedUArray ty
    forall l. IsList l => [Item l] -> l
    fromList (([ty], [ty]) -> (ChunkedUArray ty, ChunkedUArray ty))
    -> (ChunkedUArray ty -> ([ty], [ty]))
    -> ChunkedUArray ty
    -> (ChunkedUArray ty, ChunkedUArray ty)
    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
    . (Element [ty] -> Bool) -> [ty] -> ([ty], [ty])
    forall c. Sequential c => (Element c -> Bool) -> c -> (c, c)
    C.breakEnd ty -> Bool
    Element [ty] -> Bool
    p ([ty] -> ([ty], [ty]))
    -> (ChunkedUArray ty -> [ty]) -> ChunkedUArray ty -> ([ty], [ty])
    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
    . ChunkedUArray ty -> [ty]
    ChunkedUArray ty -> [Item (ChunkedUArray ty)]
    forall l. IsList l => l -> [Item l]
    toList

    -- TODO: Improve implementation.
    intersperse :: PrimType ty => ty -> ChunkedUArray ty -> ChunkedUArray ty
    intersperse :: forall ty.
    PrimType ty =>
    ty -> ChunkedUArray ty -> ChunkedUArray ty
    intersperse ty
    el = [ty] -> ChunkedUArray ty
    [Item (ChunkedUArray ty)] -> ChunkedUArray ty
    forall l. IsList l => [Item l] -> l
    fromList ([ty] -> ChunkedUArray ty)
    -> (ChunkedUArray ty -> [ty])
    -> ChunkedUArray ty
    -> ChunkedUArray ty
    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
    . Element [ty] -> [ty] -> [ty]
    forall c. Sequential c => Element c -> c -> c
    C.intersperse ty
    Element [ty]
    el ([ty] -> [ty])
    -> (ChunkedUArray ty -> [ty]) -> ChunkedUArray ty -> [ty]
    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
    . ChunkedUArray ty -> [ty]
    ChunkedUArray ty -> [Item (ChunkedUArray ty)]
    forall l. IsList l => l -> [Item l]
    toList

    -- TODO: Improve implementation.
    reverse :: PrimType ty => ChunkedUArray ty -> ChunkedUArray ty
    reverse :: forall ty. PrimType ty => ChunkedUArray ty -> ChunkedUArray ty
    reverse = [ty] -> ChunkedUArray ty
    [Item (ChunkedUArray ty)] -> ChunkedUArray ty
    forall l. IsList l => [Item l] -> l
    fromList ([ty] -> ChunkedUArray ty)
    -> (ChunkedUArray ty -> [ty])
    -> ChunkedUArray ty
    -> ChunkedUArray ty
    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
    . [ty] -> [ty]
    forall c. Sequential c => c -> c
    C.reverse ([ty] -> [ty])
    -> (ChunkedUArray ty -> [ty]) -> ChunkedUArray ty -> [ty]
    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
    . ChunkedUArray ty -> [ty]
    ChunkedUArray ty -> [Item (ChunkedUArray ty)]
    forall l. IsList l => l -> [Item l]
    toList

    -- TODO: Improve implementation.
    filter :: PrimType ty => (ty -> Bool) -> ChunkedUArray ty -> ChunkedUArray ty
    filter :: forall ty.
    PrimType ty =>
    (ty -> Bool) -> ChunkedUArray ty -> ChunkedUArray ty
    filter ty -> Bool
    p = [ty] -> ChunkedUArray ty
    [Item (ChunkedUArray ty)] -> ChunkedUArray ty
    forall l. IsList l => [Item l] -> l
    fromList ([ty] -> ChunkedUArray ty)
    -> (ChunkedUArray ty -> [ty])
    -> ChunkedUArray ty
    -> ChunkedUArray ty
    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
    . (Element [ty] -> Bool) -> [ty] -> [ty]
    forall c. Sequential c => (Element c -> Bool) -> c -> c
    C.filter ty -> Bool
    Element [ty] -> Bool
    p ([ty] -> [ty])
    -> (ChunkedUArray ty -> [ty]) -> ChunkedUArray ty -> [ty]
    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
    . ChunkedUArray ty -> [ty]
    ChunkedUArray ty -> [Item (ChunkedUArray ty)]
    forall l. IsList l => l -> [Item l]
    toList

    -- TODO: Improve implementation.
    unsnoc :: PrimType ty => ChunkedUArray ty -> Maybe (ChunkedUArray ty, ty)
    unsnoc :: forall ty.
    PrimType ty =>
    ChunkedUArray ty -> Maybe (ChunkedUArray ty, ty)
    unsnoc ChunkedUArray ty
    v = ([ty] -> ChunkedUArray ty) -> ([ty], ty) -> (ChunkedUArray ty, ty)
    forall a b c. (a -> b) -> (a, c) -> (b, c)
    forall (p :: * -> * -> *) a b c.
    Bifunctor p =>
    (a -> b) -> p a c -> p b c
    first [ty] -> ChunkedUArray ty
    [Item (ChunkedUArray ty)] -> ChunkedUArray ty
    forall l. IsList l => [Item l] -> l
    fromList (([ty], ty) -> (ChunkedUArray ty, ty))
    -> Maybe ([ty], ty) -> Maybe (ChunkedUArray ty, ty)
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> ([ty] -> Maybe ([ty], Element [ty])
    forall c. Sequential c => c -> Maybe (c, Element c)
    C.unsnoc ([ty] -> Maybe ([ty], Element [ty]))
    -> [ty] -> Maybe ([ty], Element [ty])
    forall a b. (a -> b) -> a -> b
    $ ChunkedUArray ty -> [Item (ChunkedUArray ty)]
    forall l. IsList l => l -> [Item l]
    toList ChunkedUArray ty
    v)

    -- TODO: Improve implementation.
    uncons :: PrimType ty => ChunkedUArray ty -> Maybe (ty, ChunkedUArray ty)
    uncons :: forall ty.
    PrimType ty =>
    ChunkedUArray ty -> Maybe (ty, ChunkedUArray ty)
    uncons ChunkedUArray ty
    v = ([ty] -> ChunkedUArray ty) -> (ty, [ty]) -> (ty, ChunkedUArray ty)
    forall b c a. (b -> c) -> (a, b) -> (a, c)
    forall (p :: * -> * -> *) b c a.
    Bifunctor p =>
    (b -> c) -> p a b -> p a c
    second [ty] -> ChunkedUArray ty
    [Item (ChunkedUArray ty)] -> ChunkedUArray ty
    forall l. IsList l => [Item l] -> l
    fromList ((ty, [ty]) -> (ty, ChunkedUArray ty))
    -> Maybe (ty, [ty]) -> Maybe (ty, ChunkedUArray ty)
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> ([ty] -> Maybe (Element [ty], [ty])
    forall c. Sequential c => c -> Maybe (Element c, c)
    C.uncons ([ty] -> Maybe (Element [ty], [ty]))
    -> [ty] -> Maybe (Element [ty], [ty])
    forall a b. (a -> b) -> a -> b
    $ ChunkedUArray ty -> [Item (ChunkedUArray ty)]
    forall l. IsList l => l -> [Item l]
    toList ChunkedUArray ty
    v)

    cons :: PrimType ty => ty -> ChunkedUArray ty -> ChunkedUArray ty
    cons :: forall ty.
    PrimType ty =>
    ty -> ChunkedUArray ty -> ChunkedUArray ty
    cons ty
    el (ChunkedUArray Array (UArray ty)
    inner) = Array (UArray ty) -> ChunkedUArray ty
    forall ty. Array (UArray ty) -> ChunkedUArray ty
    ChunkedUArray (Array (UArray ty) -> ChunkedUArray ty)
    -> Array (UArray ty) -> ChunkedUArray ty
    forall a b. (a -> b) -> a -> b
    $ (forall s. ST s (Array (UArray ty))) -> Array (UArray ty)
    forall a. (forall s. ST s a) -> a
    runST ((forall s. ST s (Array (UArray ty))) -> Array (UArray ty))
    -> (forall s. ST s (Array (UArray ty))) -> Array (UArray ty)
    forall a b. (a -> b) -> a -> b
    $ do
      let newLen :: CountOf (UArray ty)
    newLen = Array (UArray ty) -> CountOf (Element (Array (UArray ty)))
    forall c. Collection c => c -> CountOf (Element c)
    C.length Array (UArray ty)
    inner CountOf (UArray ty) -> CountOf (UArray ty) -> CountOf (UArray ty)
    forall a. Additive a => a -> a -> a
    + CountOf (UArray ty)
    1
      MArray (UArray ty) s
    newArray   <- CountOf (UArray ty) -> ST s (MArray (UArray ty) (PrimState (ST s)))
    forall (prim :: * -> *) ty.
    PrimMonad prim =>
    CountOf ty -> prim (MArray ty (PrimState prim))
    A.new CountOf (UArray ty)
    newLen
      let single :: UArray ty
    single = [Item (UArray ty)] -> UArray ty
    forall l. IsList l => [Item l] -> l
    fromList [ty
    Item (UArray ty)
    el]
      MArray (UArray ty) (PrimState (ST s))
    -> Offset (UArray ty) -> UArray ty -> ST s ()
    forall (prim :: * -> *) ty.
    PrimMonad prim =>
    MArray ty (PrimState prim) -> Offset ty -> ty -> prim ()
    A.unsafeWrite MArray (UArray ty) s
    MArray (UArray ty) (PrimState (ST s))
    newArray Offset (UArray ty)
    0 UArray ty
    single
      MArray (UArray ty) (PrimState (ST s))
    -> Offset (UArray ty)
    -> Array (UArray ty)
    -> Offset (UArray ty)
    -> CountOf (UArray ty)
    -> ST s ()
    forall (prim :: * -> *) ty.
    PrimMonad prim =>
    MArray ty (PrimState prim)
    -> Offset ty -> Array ty -> Offset ty -> CountOf ty -> prim ()
    A.unsafeCopyAtRO MArray (UArray ty) s
    MArray (UArray ty) (PrimState (ST s))
    newArray (Int -> Offset (UArray ty)
    forall ty. Int -> Offset ty
    Offset Int
    1) Array (UArray ty)
    inner (Int -> Offset (UArray ty)
    forall ty. Int -> Offset ty
    Offset Int
    0) (Array (UArray ty) -> CountOf (Element (Array (UArray ty)))
    forall c. Collection c => c -> CountOf (Element c)
    C.length Array (UArray ty)
    inner)
      MArray (UArray ty) (PrimState (ST s)) -> ST s (Array (UArray ty))
    forall (prim :: * -> *) ty.
    PrimMonad prim =>
    MArray ty (PrimState prim) -> prim (Array ty)
    A.unsafeFreeze MArray (UArray ty) s
    MArray (UArray ty) (PrimState (ST s))
    newArray

    snoc :: PrimType ty => ChunkedUArray ty -> ty -> ChunkedUArray ty
    snoc :: forall ty.
    PrimType ty =>
    ChunkedUArray ty -> ty -> ChunkedUArray ty
    snoc (ChunkedUArray Array (UArray ty)
    spine) ty
    el = Array (UArray ty) -> ChunkedUArray ty
    forall ty. Array (UArray ty) -> ChunkedUArray ty
    ChunkedUArray (Array (UArray ty) -> ChunkedUArray ty)
    -> Array (UArray ty) -> ChunkedUArray ty
    forall a b. (a -> b) -> a -> b
    $ (forall s. ST s (Array (UArray ty))) -> Array (UArray ty)
    forall a. (forall s. ST s a) -> a
    runST ((forall s. ST s (Array (UArray ty))) -> Array (UArray ty))
    -> (forall s. ST s (Array (UArray ty))) -> Array (UArray ty)
    forall a b. (a -> b) -> a -> b
    $ do
      MArray (UArray ty) s
    newArray  <- CountOf (UArray ty) -> ST s (MArray (UArray ty) (PrimState (ST s)))
    forall (prim :: * -> *) ty.
    PrimMonad prim =>
    CountOf ty -> prim (MArray ty (PrimState prim))
    A.new (Array (UArray ty) -> CountOf (UArray ty)
    forall a. Array a -> CountOf a
    A.length Array (UArray ty)
    spine CountOf (UArray ty) -> CountOf (UArray ty) -> CountOf (UArray ty)
    forall a. Additive a => a -> a -> a
    + CountOf (UArray ty)
    1)
      let single :: UArray ty
    single = ty -> UArray ty
    forall ty. PrimType ty => ty -> UArray ty
    U.singleton ty
    el
      MArray (UArray ty) (PrimState (ST s))
    -> Offset (UArray ty)
    -> Array (UArray ty)
    -> Offset (UArray ty)
    -> CountOf (UArray ty)
    -> ST s ()
    forall (prim :: * -> *) ty.
    PrimMonad prim =>
    MArray ty (PrimState prim)
    -> Offset ty -> Array ty -> Offset ty -> CountOf ty -> prim ()
    A.unsafeCopyAtRO MArray (UArray ty) s
    MArray (UArray ty) (PrimState (ST s))
    newArray (Int -> Offset (UArray ty)
    forall ty. Int -> Offset ty
    Offset Int
    0) Array (UArray ty)
    spine (Int -> Offset (UArray ty)
    forall ty. Int -> Offset ty
    Offset Int
    0) (Array (UArray ty) -> CountOf (Element (Array (UArray ty)))
    forall c. Collection c => c -> CountOf (Element c)
    C.length Array (UArray ty)
    spine)
      MArray (UArray ty) (PrimState (ST s))
    -> Offset (UArray ty) -> UArray ty -> ST s ()
    forall (prim :: * -> *) ty.
    PrimMonad prim =>
    MArray ty (PrimState prim) -> Offset ty -> ty -> prim ()
    A.unsafeWrite MArray (UArray ty) s
    MArray (UArray ty) (PrimState (ST s))
    newArray (CountOf (UArray ty) -> Offset (UArray ty)
    forall a. CountOf a -> Offset a
    sizeAsOffset (CountOf (UArray ty) -> Offset (UArray ty))
    -> CountOf (UArray ty) -> Offset (UArray ty)
    forall a b. (a -> b) -> a -> b
    $ Array (UArray ty) -> CountOf (UArray ty)
    forall a. Array a -> CountOf a
    A.length Array (UArray ty)
    spine) UArray ty
    single
      MArray (UArray ty) (PrimState (ST s)) -> ST s (Array (UArray ty))
    forall (prim :: * -> *) ty.
    PrimMonad prim =>
    MArray ty (PrimState prim) -> prim (Array ty)
    A.unsafeFreeze MArray (UArray ty) s
    MArray (UArray ty) (PrimState (ST s))
    newArray

    -- TODO optimise
    find :: PrimType ty => (ty -> Bool) -> ChunkedUArray ty -> Maybe ty
    find :: forall ty.
    PrimType ty =>
    (ty -> Bool) -> ChunkedUArray ty -> Maybe ty
    find ty -> Bool
    fn ChunkedUArray ty
    v = Offset ty -> Maybe ty
    loop Offset ty
    0
      where
        len :: CountOf ty
    len = ChunkedUArray ty -> CountOf ty
    forall ty. PrimType ty => ChunkedUArray ty -> CountOf ty
    length ChunkedUArray ty
    v
        loop :: Offset ty -> Maybe ty
    loop !Offset ty
    idx
          | Offset ty
    idx Offset ty -> CountOf ty -> Bool
    forall ty. Offset ty -> CountOf ty -> Bool
    .==# CountOf ty
    len = Maybe ty
    forall a. Maybe a
    Nothing
          | Bool
    otherwise    =
            let currentElem :: ty
    currentElem = ChunkedUArray ty
    v ChunkedUArray ty -> Offset ty -> ty
    forall ty. PrimType ty => ChunkedUArray ty -> Offset ty -> ty
    `unsafeIndex` Offset ty
    idx
            in case ty -> Bool
    fn ty
    currentElem of
              Bool
    True  -> ty -> Maybe ty
    forall a. a -> Maybe a
    Just ty
    currentElem
              Bool
    False -> Offset ty -> Maybe ty
    loop (Offset ty
    idx Offset ty -> Offset ty -> Offset ty
    forall a. Additive a => a -> a -> a
    + Offset ty
    1)

    -- TODO: Improve implementation.
    sortBy :: PrimType ty => (ty -> ty -> Ordering) -> ChunkedUArray ty -> ChunkedUArray ty
    sortBy :: forall ty.
    PrimType ty =>
    (ty -> ty -> Ordering) -> ChunkedUArray ty -> ChunkedUArray ty
    sortBy ty -> ty -> Ordering
    p = [ty] -> ChunkedUArray ty
    [Item (ChunkedUArray ty)] -> ChunkedUArray ty
    forall l. IsList l => [Item l] -> l
    fromList ([ty] -> ChunkedUArray ty)
    -> (ChunkedUArray ty -> [ty])
    -> ChunkedUArray ty
    -> ChunkedUArray ty
    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
    . (Element [ty] -> Element [ty] -> Ordering) -> [ty] -> [ty]
    forall c.
    Sequential c =>
    (Element c -> Element c -> Ordering) -> c -> c
    C.sortBy ty -> ty -> Ordering
    Element [ty] -> Element [ty] -> Ordering
    p ([ty] -> [ty])
    -> (ChunkedUArray ty -> [ty]) -> ChunkedUArray ty -> [ty]
    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
    . ChunkedUArray ty -> [ty]
    ChunkedUArray ty -> [Item (ChunkedUArray ty)]
    forall l. IsList l => l -> [Item l]
    toList

    index :: PrimType ty => ChunkedUArray ty -> Offset ty -> ty
    index :: forall ty. PrimType ty => ChunkedUArray ty -> Offset ty -> ty
    index ChunkedUArray ty
    array Offset ty
    n
        | Offset ty -> CountOf ty -> Bool
    forall ty. Offset ty -> CountOf ty -> Bool
    isOutOfBound Offset ty
    n CountOf ty
    len = OutOfBoundOperation -> Offset ty -> CountOf ty -> ty
    forall ty a. OutOfBoundOperation -> Offset ty -> CountOf ty -> a
    outOfBound OutOfBoundOperation
    OOB_Index Offset ty
    n CountOf ty
    len
        | Bool
    otherwise          = ChunkedUArray ty -> Offset ty -> ty
    forall ty. PrimType ty => ChunkedUArray ty -> Offset ty -> ty
    unsafeIndex ChunkedUArray ty
    array Offset ty
    n
      where len :: CountOf ty
    len = ChunkedUArray ty -> CountOf ty
    forall ty. PrimType ty => ChunkedUArray ty -> CountOf ty
    length ChunkedUArray ty
    array
    {-# INLINE index #-}

    unsafeIndex :: PrimType ty => ChunkedUArray ty -> Offset ty -> ty
    unsafeIndex :: forall ty. PrimType ty => ChunkedUArray ty -> Offset ty -> ty
    unsafeIndex (ChunkedUArray Array (UArray ty)
    array) Offset ty
    idx = UArray ty -> Offset (UArray ty) -> Offset ty -> ty
    go (Array (UArray ty) -> Offset (UArray ty) -> UArray ty
    forall ty. Array ty -> Offset ty -> ty
    A.unsafeIndex Array (UArray ty)
    array Offset (UArray ty)
    0) Offset (UArray ty)
    0 Offset ty
    idx
      where
        go :: UArray ty -> Offset (UArray ty) -> Offset ty -> ty
    go UArray ty
    u Offset (UArray ty)
    globalIndex Offset ty
    0 = case UArray ty -> Bool
    forall c. Collection c => c -> Bool
    C.null UArray ty
    u of
          -- Skip empty chunks.
          Bool
    True  -> UArray ty -> Offset (UArray ty) -> Offset ty -> ty
    go (Array (UArray ty) -> Offset (UArray ty) -> UArray ty
    forall ty. Array ty -> Offset ty -> ty
    A.unsafeIndex Array (UArray ty)
    array (Offset (UArray ty)
    globalIndex Offset (UArray ty) -> Offset (UArray ty) -> Offset (UArray ty)
    forall a. Additive a => a -> a -> a
    + Offset (UArray ty)
    1)) (Offset (UArray ty)
    globalIndex Offset (UArray ty) -> Offset (UArray ty) -> Offset (UArray ty)
    forall a. Additive a => a -> a -> a
    + Offset (UArray ty)
    1) Offset ty
    0
          Bool
    False -> UArray ty -> Offset ty -> ty
    forall ty. PrimType ty => UArray ty -> Offset ty -> ty
    U.unsafeIndex UArray ty
    u Offset ty
    0
        go UArray ty
    u !Offset (UArray ty)
    globalIndex !Offset ty
    i
          -- Skip empty chunks.
          | UArray ty -> Bool
    forall c. Collection c => c -> Bool
    C.null UArray ty
    u  = UArray ty -> Offset (UArray ty) -> Offset ty -> ty
    go (Array (UArray ty) -> Offset (UArray ty) -> UArray ty
    forall ty. Array ty -> Offset ty -> ty
    A.unsafeIndex Array (UArray ty)
    array (Offset (UArray ty)
    globalIndex Offset (UArray ty) -> Offset (UArray ty) -> Offset (UArray ty)
    forall a. Additive a => a -> a -> a
    + Offset (UArray ty)
    1)) (Offset (UArray ty)
    globalIndex Offset (UArray ty) -> Offset (UArray ty) -> Offset (UArray ty)
    forall a. Additive a => a -> a -> a
    + Offset (UArray ty)
    1) Offset ty
    i
          | Bool
    otherwise =
              case Offset ty -> CountOf ty -> Maybe (Offset ty)
    forall ty. Offset ty -> CountOf ty -> Maybe (Offset ty)
    removeArraySize Offset ty
    i (UArray ty -> CountOf ty
    forall ty. UArray ty -> CountOf ty
    U.length UArray ty
    u) of
                  Just Offset ty
    i' -> UArray ty -> Offset (UArray ty) -> Offset ty -> ty
    go (Array (UArray ty) -> Offset (UArray ty) -> UArray ty
    forall ty. Array ty -> Offset ty -> ty
    A.unsafeIndex Array (UArray ty)
    array (Offset (UArray ty)
    globalIndex Offset (UArray ty) -> Offset (UArray ty) -> Offset (UArray ty)
    forall a. Additive a => a -> a -> a
    + Offset (UArray ty)
    1)) (Offset (UArray ty)
    globalIndex Offset (UArray ty) -> Offset (UArray ty) -> Offset (UArray ty)
    forall a. Additive a => a -> a -> a
    + Offset (UArray ty)
    1) Offset ty
    i'
                  Maybe (Offset ty)
    Nothing -> UArray ty -> Offset ty -> ty
    forall ty. PrimType ty => UArray ty -> Offset ty -> ty
    U.unsafeIndex UArray ty
    u Offset ty
    i

    {-# INLINE unsafeIndex #-}

    removeArraySize :: Offset ty -> CountOf ty -> Maybe (Offset ty)
    removeArraySize :: forall ty. Offset ty -> CountOf ty -> Maybe (Offset ty)
    removeArraySize (Offset Int
    ty) (CountOf Int
    s)
        | Int
    ty Int -> Int -> Bool
    forall a. Ord a => a -> a -> Bool
    >= Int
    s   = Offset ty -> Maybe (Offset ty)
    forall a. a -> Maybe a
    Just (Int -> Offset ty
    forall ty. Int -> Offset ty
    Offset (Int
    ty Int -> Int -> Difference Int
    forall a. Subtractive a => a -> a -> Difference a
    - Int
    s))
        | Bool
    otherwise = Maybe (Offset ty)
    forall a. Maybe a
    Nothing