{-# language BangPatterns #-}
{-# language MagicHash #-}
{-# language RankNTypes #-}
{-# language ScopedTypeVariables #-}
{-# language TypeFamilies #-}
{-# language UnboxedTuples #-}
{-# language RoleAnnotations #-}

-- |
-- A version of the 'Data.Primitive.Unlifted.SmallArray' interface
-- specialized to 'ST'. This is intended primarily so library
-- developers can easily check whether the basic operations are
-- unboxed properly, but its more constrained type signatures
-- also offer somewhat better type inference where applicable.
module Data.Primitive.Unlifted.SmallArray.ST
  ( -- * Types
    SmallUnliftedArray_(..)
  , SmallUnliftedArray
  , SmallMutableUnliftedArray_(..)
  , SmallMutableUnliftedArray
    -- * Operations
  , newSmallUnliftedArray
  , unsafeNewSmallUnliftedArray
  , sizeofSmallUnliftedArray
  , getSizeofSmallMutableUnliftedArray
  , sameSmallMutableUnliftedArray
  , shrinkSmallMutableUnliftedArray
  , writeSmallUnliftedArray
  , readSmallUnliftedArray
  , indexSmallUnliftedArray
  , unsafeFreezeSmallUnliftedArray
  , freezeSmallUnliftedArray
  , thawSmallUnliftedArray
  , unsafeThawSmallUnliftedArray
  , setSmallUnliftedArray
  , copySmallUnliftedArray
  , copySmallMutableUnliftedArray
  , cloneSmallUnliftedArray
  , cloneSmallMutableUnliftedArray
  , emptySmallUnliftedArray
  , singletonSmallUnliftedArray
  , runSmallUnliftedArray
  , dupableRunSmallUnliftedArray
    -- * List Conversion
  , smallUnliftedArrayToList
  , smallUnliftedArrayFromList
  , smallUnliftedArrayFromListN
    -- * Folding
  , foldrSmallUnliftedArray
  , foldrSmallUnliftedArray'
  , foldlSmallUnliftedArray
  , foldlSmallUnliftedArray'
  , foldlSmallUnliftedArrayM'
    -- * Traversals
  , traverseSmallUnliftedArray_
  , itraverseSmallUnliftedArray_
    -- * Mapping
  , mapSmallUnliftedArray
  ) where

import Data.Primitive.Unlifted.Class (PrimUnlifted (..))
import Data.Primitive.Unlifted.SmallArray.Primops
import GHC.Exts (Int(I#),State#)
import GHC.ST (ST (..))

import qualified Data.List as L
import qualified GHC.Exts as Exts

-- | Using a specialized copy of primitive_ here makes the Core a little
-- easier to read by eliminating unnecessary PrimState coercions.
primitive_ :: (State# s -> State# s) -> ST s ()
{-# INLINE primitive_ #-}
primitive_ :: (State# s -> State# s) -> ST s ()
primitive_ State# s -> State# s
m = STRep s () -> ST s ()
forall s a. STRep s a -> ST s a
ST (\State# s
s -> (# State# s -> State# s
m State# s
s, () #))

-- | A @SmallUnliftedArray_ a unlifted_a@ represents an array of values of a
-- lifted type @a@ that wrap values of an unlifted type @unlifted_a@.
-- It is expected that @unlifted_a ~ Unlifted a@, but imposing that constraint
-- here would force the type roles to @nominal@, which is often undesirable
-- when arrays are used as components of larger datatypes.
data SmallUnliftedArray_ a unlifted_a
  = SmallUnliftedArray (SmallUnliftedArray# unlifted_a)
type role SmallUnliftedArray_ phantom representational

-- | A type synonym for a 'SmallUnliftedArray_' containing lifted values of
-- a particular type. As a general rule, this type synonym should not be used in
-- class instances—use 'SmallUnliftedArray_' with an equality constraint instead.
-- It also should not be used when defining newtypes or datatypes, unless those
-- will have restrictive type roles regardless—use 'SmallUnliftedArray_' instead.
type SmallUnliftedArray a = SmallUnliftedArray_ a (Unlifted a)

data SmallMutableUnliftedArray_ s a unlifted_a
  = SmallMutableUnliftedArray (SmallMutableUnliftedArray# s unlifted_a)
type role SmallMutableUnliftedArray_ nominal phantom representational

type SmallMutableUnliftedArray s a = SmallMutableUnliftedArray_ s a (Unlifted a)

instance unlifted_a ~ Unlifted a => PrimUnlifted (SmallUnliftedArray_ a unlifted_a) where
  type Unlifted (SmallUnliftedArray_ _ unlifted_a) = SmallUnliftedArray# unlifted_a
  toUnlifted# :: SmallUnliftedArray_ a unlifted_a
-> Unlifted (SmallUnliftedArray_ a unlifted_a)
toUnlifted# (SmallUnliftedArray SmallUnliftedArray# unlifted_a
a) = Unlifted (SmallUnliftedArray_ a unlifted_a)
SmallUnliftedArray# unlifted_a
a
  fromUnlifted# :: Unlifted (SmallUnliftedArray_ a unlifted_a)
-> SmallUnliftedArray_ a unlifted_a
fromUnlifted# Unlifted (SmallUnliftedArray_ a unlifted_a)
x = SmallUnliftedArray# unlifted_a -> SmallUnliftedArray_ a unlifted_a
forall a (unlifted_a :: TYPE 'UnliftedRep).
SmallUnliftedArray# unlifted_a -> SmallUnliftedArray_ a unlifted_a
SmallUnliftedArray Unlifted (SmallUnliftedArray_ a unlifted_a)
SmallUnliftedArray# unlifted_a
x

instance unlifted_a ~ Unlifted a => PrimUnlifted (SmallMutableUnliftedArray_ s a unlifted_a) where
  type Unlifted (SmallMutableUnliftedArray_ s _ unlifted_a) = SmallMutableUnliftedArray# s unlifted_a
  toUnlifted# :: SmallMutableUnliftedArray_ s a unlifted_a
-> Unlifted (SmallMutableUnliftedArray_ s a unlifted_a)
toUnlifted# (SmallMutableUnliftedArray SmallMutableUnliftedArray# s unlifted_a
a) = Unlifted (SmallMutableUnliftedArray_ s a unlifted_a)
SmallMutableUnliftedArray# s unlifted_a
a
  fromUnlifted# :: Unlifted (SmallMutableUnliftedArray_ s a unlifted_a)
-> SmallMutableUnliftedArray_ s a unlifted_a
fromUnlifted# Unlifted (SmallMutableUnliftedArray_ s a unlifted_a)
x = SmallMutableUnliftedArray# s unlifted_a
-> SmallMutableUnliftedArray_ s a unlifted_a
forall s a (unlifted_a :: TYPE 'UnliftedRep).
SmallMutableUnliftedArray# s unlifted_a
-> SmallMutableUnliftedArray_ s a unlifted_a
SmallMutableUnliftedArray Unlifted (SmallMutableUnliftedArray_ s a unlifted_a)
SmallMutableUnliftedArray# s unlifted_a
x

-- | Creates a new 'MutableUnliftedArray' with the specified value as initial
-- contents.
newSmallUnliftedArray
  :: PrimUnlifted a
  => Int -- ^ size
  -> a -- ^ initial value
  -> ST s (SmallMutableUnliftedArray s a)
newSmallUnliftedArray :: Int -> a -> ST s (SmallMutableUnliftedArray s a)
newSmallUnliftedArray (I# Int#
len) a
v = STRep s (SmallMutableUnliftedArray s a)
-> ST s (SmallMutableUnliftedArray s a)
forall s a. STRep s a -> ST s a
ST (STRep s (SmallMutableUnliftedArray s a)
 -> ST s (SmallMutableUnliftedArray s a))
-> STRep s (SmallMutableUnliftedArray s a)
-> ST s (SmallMutableUnliftedArray s a)
forall a b. (a -> b) -> a -> b
$ \State# s
s -> case Int#
-> Unlifted a
-> State# s
-> (# State# s, SmallMutableUnliftedArray# s (Unlifted a) #)
forall (a :: TYPE 'UnliftedRep) s.
Int#
-> a -> State# s -> (# State# s, SmallMutableUnliftedArray# s a #)
newSmallUnliftedArray# Int#
len (a -> Unlifted a
forall a. PrimUnlifted a => a -> Unlifted a
toUnlifted# a
v) State# s
s of
  (# State# s
s', SmallMutableUnliftedArray# s (Unlifted a)
ma #) -> (# State# s
s', SmallMutableUnliftedArray# s (Unlifted a)
-> SmallMutableUnliftedArray s a
forall s a (unlifted_a :: TYPE 'UnliftedRep).
SmallMutableUnliftedArray# s unlifted_a
-> SmallMutableUnliftedArray_ s a unlifted_a
SmallMutableUnliftedArray SmallMutableUnliftedArray# s (Unlifted a)
ma #)
{-# inline newSmallUnliftedArray #-}

setSmallUnliftedArray
  :: PrimUnlifted a
  => SmallMutableUnliftedArray s a -- ^ destination
  -> a -- ^ value to fill with
  -> Int -- ^ offset
  -> Int -- ^ length
  -> ST s ()
{-# inline setSmallUnliftedArray #-}
setSmallUnliftedArray :: SmallMutableUnliftedArray s a -> a -> Int -> Int -> ST s ()
setSmallUnliftedArray SmallMutableUnliftedArray s a
mua a
v Int
off Int
len = Int -> ST s ()
loop (Int
len Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
off Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1)
 where
 loop :: Int -> ST s ()
loop Int
i
   | Int
i Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
off = () -> ST s ()
forall (f :: * -> *) a. Applicative f => a -> f a
pure ()
   | Bool
otherwise = SmallMutableUnliftedArray s a -> Int -> a -> ST s ()
forall a s.
PrimUnlifted a =>
SmallMutableUnliftedArray s a -> Int -> a -> ST s ()
writeSmallUnliftedArray SmallMutableUnliftedArray s a
mua Int
i a
v ST s () -> ST s () -> ST s ()
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> Int -> ST s ()
loop (Int
iInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1)

-- | Yields the length of an 'UnliftedArray'.
sizeofSmallUnliftedArray :: SmallUnliftedArray e -> Int
{-# inline sizeofSmallUnliftedArray #-}
sizeofSmallUnliftedArray :: SmallUnliftedArray e -> Int
sizeofSmallUnliftedArray (SmallUnliftedArray SmallUnliftedArray# (Unlifted e)
ar) = Int# -> Int
I# (SmallUnliftedArray# (Unlifted e) -> Int#
forall (a :: TYPE 'UnliftedRep). SmallUnliftedArray# a -> Int#
sizeofSmallUnliftedArray# SmallUnliftedArray# (Unlifted e)
ar)

-- | Yields the length of a 'MutableUnliftedArray'.
getSizeofSmallMutableUnliftedArray :: SmallMutableUnliftedArray s e -> ST s Int
{-# inline getSizeofSmallMutableUnliftedArray #-}
getSizeofSmallMutableUnliftedArray :: SmallMutableUnliftedArray s e -> ST s Int
getSizeofSmallMutableUnliftedArray (SmallMutableUnliftedArray SmallMutableUnliftedArray# s (Unlifted e)
maa#)
  = STRep s Int -> ST s Int
forall s a. STRep s a -> ST s a
ST (\State# s
s -> case SmallMutableUnliftedArray# s (Unlifted e)
-> State# s -> (# State# s, Int# #)
forall s (a :: TYPE 'UnliftedRep).
SmallMutableUnliftedArray# s a -> State# s -> (# State# s, Int# #)
getSizeofSmallMutableUnliftedArray# SmallMutableUnliftedArray# s (Unlifted e)
maa# State# s
s of
      (# State# s
s', Int#
sz #) -> (# State# s
s', Int# -> Int
I# Int#
sz #))

writeSmallUnliftedArray :: PrimUnlifted a
  => SmallMutableUnliftedArray s a
  -> Int
  -> a
  -> ST s ()
{-# inline writeSmallUnliftedArray #-}
writeSmallUnliftedArray :: SmallMutableUnliftedArray s a -> Int -> a -> ST s ()
writeSmallUnliftedArray (SmallMutableUnliftedArray SmallMutableUnliftedArray# s (Unlifted a)
arr) (I# Int#
ix) a
a =
  (State# s -> State# s) -> ST s ()
forall s. (State# s -> State# s) -> ST s ()
primitive_ (SmallMutableUnliftedArray# s (Unlifted a)
-> Int# -> Unlifted a -> State# s -> State# s
forall s (a :: TYPE 'UnliftedRep).
SmallMutableUnliftedArray# s a -> Int# -> a -> State# s -> State# s
writeSmallUnliftedArray# SmallMutableUnliftedArray# s (Unlifted a)
arr Int#
ix (a -> Unlifted a
forall a. PrimUnlifted a => a -> Unlifted a
toUnlifted# a
a))

readSmallUnliftedArray :: PrimUnlifted a
  => SmallMutableUnliftedArray s a
  -> Int
  -> ST s a
{-# inline readSmallUnliftedArray #-}
readSmallUnliftedArray :: SmallMutableUnliftedArray s a -> Int -> ST s a
readSmallUnliftedArray (SmallMutableUnliftedArray SmallMutableUnliftedArray# s (Unlifted a)
arr) (I# Int#
ix) =
  STRep s a -> ST s a
forall s a. STRep s a -> ST s a
ST (STRep s a -> ST s a) -> STRep s a -> ST s a
forall a b. (a -> b) -> a -> b
$ \State# s
s -> case SmallMutableUnliftedArray# s (Unlifted a)
-> Int# -> State# s -> (# State# s, Unlifted a #)
forall s (a :: TYPE 'UnliftedRep).
SmallMutableUnliftedArray# s a
-> Int# -> State# s -> (# State# s, a #)
readSmallUnliftedArray# SmallMutableUnliftedArray# s (Unlifted a)
arr Int#
ix State# s
s of
    (# State# s
s', Unlifted a
a #) -> (# State# s
s', Unlifted a -> a
forall a. PrimUnlifted a => Unlifted a -> a
fromUnlifted# Unlifted a
a #)

indexSmallUnliftedArray :: PrimUnlifted a
  => SmallUnliftedArray a
  -> Int
  -> a
{-# inline indexSmallUnliftedArray #-}
indexSmallUnliftedArray :: SmallUnliftedArray a -> Int -> a
indexSmallUnliftedArray (SmallUnliftedArray SmallUnliftedArray# (Unlifted a)
arr) (I# Int#
ix) =
  Unlifted a -> a
forall a. PrimUnlifted a => Unlifted a -> a
fromUnlifted# (SmallUnliftedArray# (Unlifted a) -> Int# -> Unlifted a
forall (a :: TYPE 'UnliftedRep). SmallUnliftedArray# a -> Int# -> a
indexSmallUnliftedArray# SmallUnliftedArray# (Unlifted a)
arr Int#
ix)

-- | Freezes a 'SmallMutableUnliftedArray', yielding a 'SmallUnliftedArray'.
-- This simply marks the array as frozen in place, so it should only be used
-- when no further modifications to the mutable array will be performed.
unsafeFreezeSmallUnliftedArray
  :: SmallMutableUnliftedArray s a
  -> ST s (SmallUnliftedArray a)
unsafeFreezeSmallUnliftedArray :: SmallMutableUnliftedArray s a -> ST s (SmallUnliftedArray a)
unsafeFreezeSmallUnliftedArray (SmallMutableUnliftedArray SmallMutableUnliftedArray# s (Unlifted a)
maa#)
  = STRep s (SmallUnliftedArray a) -> ST s (SmallUnliftedArray a)
forall s a. STRep s a -> ST s a
ST (STRep s (SmallUnliftedArray a) -> ST s (SmallUnliftedArray a))
-> STRep s (SmallUnliftedArray a) -> ST s (SmallUnliftedArray a)
forall a b. (a -> b) -> a -> b
$ \State# s
s -> case SmallMutableUnliftedArray# s (Unlifted a)
-> State# s -> (# State# s, SmallUnliftedArray# (Unlifted a) #)
forall s (a :: TYPE 'UnliftedRep).
SmallMutableUnliftedArray# s a
-> State# s -> (# State# s, SmallUnliftedArray# a #)
unsafeFreezeSmallUnliftedArray# SmallMutableUnliftedArray# s (Unlifted a)
maa# State# s
s of
      (# State# s
s', SmallUnliftedArray# (Unlifted a)
aa# #) -> (# State# s
s', SmallUnliftedArray# (Unlifted a) -> SmallUnliftedArray a
forall a (unlifted_a :: TYPE 'UnliftedRep).
SmallUnliftedArray# unlifted_a -> SmallUnliftedArray_ a unlifted_a
SmallUnliftedArray SmallUnliftedArray# (Unlifted a)
aa# #)
{-# inline unsafeFreezeSmallUnliftedArray #-}

-- | Determines whether two 'MutableUnliftedArray' values are the same. This is
-- object/pointer identity, not based on the contents.
sameSmallMutableUnliftedArray
  :: SmallMutableUnliftedArray s a
  -> SmallMutableUnliftedArray s a
  -> Bool
sameSmallMutableUnliftedArray :: SmallMutableUnliftedArray s a
-> SmallMutableUnliftedArray s a -> Bool
sameSmallMutableUnliftedArray (SmallMutableUnliftedArray SmallMutableUnliftedArray# s (Unlifted a)
maa1#) (SmallMutableUnliftedArray SmallMutableUnliftedArray# s (Unlifted a)
maa2#)
  = Int# -> Bool
Exts.isTrue# (SmallMutableUnliftedArray# s (Unlifted a)
-> SmallMutableUnliftedArray# s (Unlifted a) -> Int#
forall s (a :: TYPE 'UnliftedRep).
SmallMutableUnliftedArray# s a
-> SmallMutableUnliftedArray# s a -> Int#
sameSmallMutableUnliftedArray# SmallMutableUnliftedArray# s (Unlifted a)
maa1# SmallMutableUnliftedArray# s (Unlifted a)
maa2#)
{-# inline sameSmallMutableUnliftedArray #-}

-- | Shrink a mutable array to the specified size. The new size argument must be less than or
-- equal to the current size.
shrinkSmallMutableUnliftedArray :: SmallMutableUnliftedArray s a -> Int -> ST s ()
shrinkSmallMutableUnliftedArray :: SmallMutableUnliftedArray s a -> Int -> ST s ()
shrinkSmallMutableUnliftedArray (SmallMutableUnliftedArray SmallMutableUnliftedArray# s (Unlifted a)
mary) (I# Int#
sz)
  = (State# s -> State# s) -> ST s ()
forall s. (State# s -> State# s) -> ST s ()
primitive_ ((State# s -> State# s) -> ST s ())
-> (State# s -> State# s) -> ST s ()
forall a b. (a -> b) -> a -> b
$ SmallMutableUnliftedArray# s (Unlifted a)
-> Int# -> State# s -> State# s
forall s (a :: TYPE 'UnliftedRep).
SmallMutableUnliftedArray# s a -> Int# -> State# s -> State# s
shrinkSmallMutableUnliftedArray# SmallMutableUnliftedArray# s (Unlifted a)
mary Int#
sz
{-# inline shrinkSmallMutableUnliftedArray #-}

-- | Copies the contents of an immutable array into a mutable array.
copySmallUnliftedArray
  :: SmallMutableUnliftedArray s a -- ^ destination
  -> Int -- ^ offset into destination
  -> SmallUnliftedArray a -- ^ source
  -> Int -- ^ offset into source
  -> Int -- ^ number of elements to copy
  -> ST s ()
{-# inline copySmallUnliftedArray #-}
copySmallUnliftedArray :: SmallMutableUnliftedArray s a
-> Int -> SmallUnliftedArray a -> Int -> Int -> ST s ()
copySmallUnliftedArray
  (SmallMutableUnliftedArray SmallMutableUnliftedArray# s (Unlifted a)
dst) (I# Int#
doff)
  (SmallUnliftedArray SmallUnliftedArray# (Unlifted a)
src) (I# Int#
soff) (I# Int#
ln) =
    (State# s -> State# s) -> ST s ()
forall s. (State# s -> State# s) -> ST s ()
primitive_ ((State# s -> State# s) -> ST s ())
-> (State# s -> State# s) -> ST s ()
forall a b. (a -> b) -> a -> b
$ SmallUnliftedArray# (Unlifted a)
-> Int#
-> SmallMutableUnliftedArray# s (Unlifted a)
-> Int#
-> Int#
-> State# s
-> State# s
forall (a :: TYPE 'UnliftedRep) s.
SmallUnliftedArray# a
-> Int#
-> SmallMutableUnliftedArray# s a
-> Int#
-> Int#
-> State# s
-> State# s
copySmallUnliftedArray# SmallUnliftedArray# (Unlifted a)
src Int#
soff SmallMutableUnliftedArray# s (Unlifted a)
dst Int#
doff Int#
ln

-- | Copies the contents of one mutable array into another.
copySmallMutableUnliftedArray
  :: SmallMutableUnliftedArray s a -- ^ destination
  -> Int -- ^ offset into destination
  -> SmallMutableUnliftedArray s a -- ^ source
  -> Int -- ^ offset into source
  -> Int -- ^ number of elements to copy
  -> ST s ()
{-# inline copySmallMutableUnliftedArray #-}
copySmallMutableUnliftedArray :: SmallMutableUnliftedArray s a
-> Int -> SmallMutableUnliftedArray s a -> Int -> Int -> ST s ()
copySmallMutableUnliftedArray
  (SmallMutableUnliftedArray SmallMutableUnliftedArray# s (Unlifted a)
dst) (I# Int#
doff)
  (SmallMutableUnliftedArray SmallMutableUnliftedArray# s (Unlifted a)
src) (I# Int#
soff) (I# Int#
ln) =
    (State# s -> State# s) -> ST s ()
forall s. (State# s -> State# s) -> ST s ()
primitive_ ((State# s -> State# s) -> ST s ())
-> (State# s -> State# s) -> ST s ()
forall a b. (a -> b) -> a -> b
$ SmallMutableUnliftedArray# s (Unlifted a)
-> Int#
-> SmallMutableUnliftedArray# s (Unlifted a)
-> Int#
-> Int#
-> State# s
-> State# s
forall s (a :: TYPE 'UnliftedRep).
SmallMutableUnliftedArray# s a
-> Int#
-> SmallMutableUnliftedArray# s a
-> Int#
-> Int#
-> State# s
-> State# s
copySmallMutableUnliftedArray# SmallMutableUnliftedArray# s (Unlifted a)
src Int#
soff SmallMutableUnliftedArray# s (Unlifted a)
dst Int#
doff Int#
ln

-- | Freezes a portion of a 'MutableUnliftedArray', yielding an 'UnliftedArray'.
-- This operation is safe, in that it copies the frozen portion, and the
-- existing mutable array may still be used afterward.
freezeSmallUnliftedArray
  :: SmallMutableUnliftedArray s a -- ^ source
  -> Int -- ^ offset
  -> Int -- ^ length
  -> ST s (SmallUnliftedArray a)
freezeSmallUnliftedArray :: SmallMutableUnliftedArray s a
-> Int -> Int -> ST s (SmallUnliftedArray a)
freezeSmallUnliftedArray (SmallMutableUnliftedArray SmallMutableUnliftedArray# s (Unlifted a)
mary) (I# Int#
off) (I# Int#
len) =
    STRep s (SmallUnliftedArray a) -> ST s (SmallUnliftedArray a)
forall s a. STRep s a -> ST s a
ST (STRep s (SmallUnliftedArray a) -> ST s (SmallUnliftedArray a))
-> STRep s (SmallUnliftedArray a) -> ST s (SmallUnliftedArray a)
forall a b. (a -> b) -> a -> b
$ \State# s
s -> case SmallMutableUnliftedArray# s (Unlifted a)
-> Int#
-> Int#
-> State# s
-> (# State# s, SmallUnliftedArray# (Unlifted a) #)
forall s (a :: TYPE 'UnliftedRep).
SmallMutableUnliftedArray# s a
-> Int#
-> Int#
-> State# s
-> (# State# s, SmallUnliftedArray# a #)
freezeSmallUnliftedArray# SmallMutableUnliftedArray# s (Unlifted a)
mary Int#
off Int#
len State# s
s of
      (# State# s
s', SmallUnliftedArray# (Unlifted a)
ary #) -> (# State# s
s', SmallUnliftedArray# (Unlifted a) -> SmallUnliftedArray a
forall a (unlifted_a :: TYPE 'UnliftedRep).
SmallUnliftedArray# unlifted_a -> SmallUnliftedArray_ a unlifted_a
SmallUnliftedArray SmallUnliftedArray# (Unlifted a)
ary #)
{-# inline freezeSmallUnliftedArray #-}

-- | Thaws a portion of a 'SmallUnliftedArray', yielding a 'SmallMutableUnliftedArray'.
-- This copies the thawed portion, so mutations will not affect the original
-- array.
thawSmallUnliftedArray
  :: SmallUnliftedArray a -- ^ source
  -> Int -- ^ offset
  -> Int -- ^ length
  -> ST s (SmallMutableUnliftedArray s a)
{-# inline thawSmallUnliftedArray #-}
thawSmallUnliftedArray :: SmallUnliftedArray a
-> Int -> Int -> ST s (SmallMutableUnliftedArray s a)
thawSmallUnliftedArray (SmallUnliftedArray SmallUnliftedArray# (Unlifted a)
ary) (I# Int#
off) (I# Int#
len) =
    STRep s (SmallMutableUnliftedArray s a)
-> ST s (SmallMutableUnliftedArray s a)
forall s a. STRep s a -> ST s a
ST (STRep s (SmallMutableUnliftedArray s a)
 -> ST s (SmallMutableUnliftedArray s a))
-> STRep s (SmallMutableUnliftedArray s a)
-> ST s (SmallMutableUnliftedArray s a)
forall a b. (a -> b) -> a -> b
$ \State# s
s -> case SmallUnliftedArray# (Unlifted a)
-> Int#
-> Int#
-> State# s
-> (# State# s, SmallMutableUnliftedArray# s (Unlifted a) #)
forall (a :: TYPE 'UnliftedRep) s.
SmallUnliftedArray# a
-> Int#
-> Int#
-> State# s
-> (# State# s, SmallMutableUnliftedArray# s a #)
thawSmallUnliftedArray# SmallUnliftedArray# (Unlifted a)
ary Int#
off Int#
len State# s
s of
      (# State# s
s', SmallMutableUnliftedArray# s (Unlifted a)
mary #) -> (# State# s
s', SmallMutableUnliftedArray# s (Unlifted a)
-> SmallMutableUnliftedArray s a
forall s a (unlifted_a :: TYPE 'UnliftedRep).
SmallMutableUnliftedArray# s unlifted_a
-> SmallMutableUnliftedArray_ s a unlifted_a
SmallMutableUnliftedArray SmallMutableUnliftedArray# s (Unlifted a)
mary #)

-- | Thaws a 'SmallUnliftedArray', yielding a 'SmallMutableUnliftedArray'.
-- This does not make a copy.
unsafeThawSmallUnliftedArray
  :: SmallUnliftedArray a -- ^ source
  -> ST s (SmallMutableUnliftedArray s a)
{-# inline unsafeThawSmallUnliftedArray #-}
unsafeThawSmallUnliftedArray :: SmallUnliftedArray a -> ST s (SmallMutableUnliftedArray s a)
unsafeThawSmallUnliftedArray (SmallUnliftedArray SmallUnliftedArray# (Unlifted a)
ary) =
    STRep s (SmallMutableUnliftedArray s a)
-> ST s (SmallMutableUnliftedArray s a)
forall s a. STRep s a -> ST s a
ST (STRep s (SmallMutableUnliftedArray s a)
 -> ST s (SmallMutableUnliftedArray s a))
-> STRep s (SmallMutableUnliftedArray s a)
-> ST s (SmallMutableUnliftedArray s a)
forall a b. (a -> b) -> a -> b
$ \State# s
s -> case SmallUnliftedArray# (Unlifted a)
-> State# s
-> (# State# s, SmallMutableUnliftedArray# s (Unlifted a) #)
forall (a :: TYPE 'UnliftedRep) s.
SmallUnliftedArray# a
-> State# s -> (# State# s, SmallMutableUnliftedArray# s a #)
unsafeThawSmallUnliftedArray# SmallUnliftedArray# (Unlifted a)
ary State# s
s of
      (# State# s
s', SmallMutableUnliftedArray# s (Unlifted a)
mary #) -> (# State# s
s', SmallMutableUnliftedArray# s (Unlifted a)
-> SmallMutableUnliftedArray s a
forall s a (unlifted_a :: TYPE 'UnliftedRep).
SmallMutableUnliftedArray# s unlifted_a
-> SmallMutableUnliftedArray_ s a unlifted_a
SmallMutableUnliftedArray SmallMutableUnliftedArray# s (Unlifted a)
mary #)

-- | Execute a stateful computation and freeze the resulting array.
runSmallUnliftedArray
  :: (forall s. ST s (SmallMutableUnliftedArray s a))
  -> SmallUnliftedArray a
{-# INLINE runSmallUnliftedArray #-}
-- This is what we'd like to write, but GHC does not yet
-- produce properly unboxed code when we do
-- runUnliftedArray m = runST $ noDuplicate >> m >>= unsafeFreezeUnliftedArray
runSmallUnliftedArray :: (forall s. ST s (SmallMutableUnliftedArray s a))
-> SmallUnliftedArray a
runSmallUnliftedArray forall s. ST s (SmallMutableUnliftedArray s a)
m = SmallUnliftedArray# (Unlifted a) -> SmallUnliftedArray a
forall a (unlifted_a :: TYPE 'UnliftedRep).
SmallUnliftedArray# unlifted_a -> SmallUnliftedArray_ a unlifted_a
SmallUnliftedArray ((forall s. ST s (SmallMutableUnliftedArray s a))
-> SmallUnliftedArray# (Unlifted a)
forall a.
(forall s. ST s (SmallMutableUnliftedArray s a))
-> SmallUnliftedArray# (Unlifted a)
runSmallUnliftedArray# forall s. ST s (SmallMutableUnliftedArray s a)
m)

runSmallUnliftedArray#
  :: (forall s. ST s (SmallMutableUnliftedArray s a))
  -> SmallUnliftedArray# (Unlifted a)
runSmallUnliftedArray# :: (forall s. ST s (SmallMutableUnliftedArray s a))
-> SmallUnliftedArray# (Unlifted a)
runSmallUnliftedArray# forall s. ST s (SmallMutableUnliftedArray s a)
m = case (State# RealWorld
 -> (# State# RealWorld, SmallUnliftedArray# (Unlifted a) #))
-> (# State# RealWorld, SmallUnliftedArray# (Unlifted a) #)
forall o. (State# RealWorld -> o) -> o
Exts.runRW# ((State# RealWorld
  -> (# State# RealWorld, SmallUnliftedArray# (Unlifted a) #))
 -> (# State# RealWorld, SmallUnliftedArray# (Unlifted a) #))
-> (State# RealWorld
    -> (# State# RealWorld, SmallUnliftedArray# (Unlifted a) #))
-> (# State# RealWorld, SmallUnliftedArray# (Unlifted a) #)
forall a b. (a -> b) -> a -> b
$ \State# RealWorld
s0 ->
  case State# RealWorld -> State# RealWorld
forall d. State# d -> State# d
Exts.noDuplicate# State# RealWorld
s0 of { State# RealWorld
s ->
  case ST RealWorld (SmallMutableUnliftedArray_ RealWorld a (Unlifted a))
-> State# RealWorld
-> (# State# RealWorld,
      SmallMutableUnliftedArray_ RealWorld a (Unlifted a) #)
forall s a. ST s a -> State# s -> (# State# s, a #)
unST ST RealWorld (SmallMutableUnliftedArray_ RealWorld a (Unlifted a))
forall s. ST s (SmallMutableUnliftedArray s a)
m State# RealWorld
s of { (# State# RealWorld
s', SmallMutableUnliftedArray SmallMutableUnliftedArray# RealWorld (Unlifted a)
mary# #) ->
  SmallMutableUnliftedArray# RealWorld (Unlifted a)
-> State# RealWorld
-> (# State# RealWorld, SmallUnliftedArray# (Unlifted a) #)
forall s (a :: TYPE 'UnliftedRep).
SmallMutableUnliftedArray# s a
-> State# s -> (# State# s, SmallUnliftedArray# a #)
unsafeFreezeSmallUnliftedArray# SmallMutableUnliftedArray# RealWorld (Unlifted a)
mary# State# RealWorld
s'}} of (# State# RealWorld
_, SmallUnliftedArray# (Unlifted a)
ary# #) -> SmallUnliftedArray# (Unlifted a)
ary#
{-# INLINE runSmallUnliftedArray# #-}

-- | Execute a stateful computation and freeze the resulting array.
-- It is possible, but unlikely, that the computation will be run
-- multiple times in multiple threads.
dupableRunSmallUnliftedArray
  :: (forall s. ST s (SmallMutableUnliftedArray s a))
  -> SmallUnliftedArray a
{-# INLINE dupableRunSmallUnliftedArray #-}
-- This is what we'd like to write, but GHC does not yet
-- produce properly unboxed code when we do
-- dupableRunUnliftedArray m = runST $ m >>= unsafeFreezeUnliftedArray
dupableRunSmallUnliftedArray :: (forall s. ST s (SmallMutableUnliftedArray s a))
-> SmallUnliftedArray a
dupableRunSmallUnliftedArray forall s. ST s (SmallMutableUnliftedArray s a)
m = SmallUnliftedArray# (Unlifted a) -> SmallUnliftedArray a
forall a (unlifted_a :: TYPE 'UnliftedRep).
SmallUnliftedArray# unlifted_a -> SmallUnliftedArray_ a unlifted_a
SmallUnliftedArray ((forall s. ST s (SmallMutableUnliftedArray s a))
-> SmallUnliftedArray# (Unlifted a)
forall a.
(forall s. ST s (SmallMutableUnliftedArray s a))
-> SmallUnliftedArray# (Unlifted a)
dupableRunSmallUnliftedArray# forall s. ST s (SmallMutableUnliftedArray s a)
m)

dupableRunSmallUnliftedArray#
  :: (forall s. ST s (SmallMutableUnliftedArray s a))
  -> SmallUnliftedArray# (Unlifted a)
dupableRunSmallUnliftedArray# :: (forall s. ST s (SmallMutableUnliftedArray s a))
-> SmallUnliftedArray# (Unlifted a)
dupableRunSmallUnliftedArray# forall s. ST s (SmallMutableUnliftedArray s a)
m = case (State# RealWorld
 -> (# State# RealWorld, SmallUnliftedArray# (Unlifted a) #))
-> (# State# RealWorld, SmallUnliftedArray# (Unlifted a) #)
forall o. (State# RealWorld -> o) -> o
Exts.runRW# ((State# RealWorld
  -> (# State# RealWorld, SmallUnliftedArray# (Unlifted a) #))
 -> (# State# RealWorld, SmallUnliftedArray# (Unlifted a) #))
-> (State# RealWorld
    -> (# State# RealWorld, SmallUnliftedArray# (Unlifted a) #))
-> (# State# RealWorld, SmallUnliftedArray# (Unlifted a) #)
forall a b. (a -> b) -> a -> b
$ \State# RealWorld
s ->
  case ST RealWorld (SmallMutableUnliftedArray_ RealWorld a (Unlifted a))
-> State# RealWorld
-> (# State# RealWorld,
      SmallMutableUnliftedArray_ RealWorld a (Unlifted a) #)
forall s a. ST s a -> State# s -> (# State# s, a #)
unST ST RealWorld (SmallMutableUnliftedArray_ RealWorld a (Unlifted a))
forall s. ST s (SmallMutableUnliftedArray s a)
m State# RealWorld
s of { (# State# RealWorld
s', SmallMutableUnliftedArray SmallMutableUnliftedArray# RealWorld (Unlifted a)
mary# #) ->
  SmallMutableUnliftedArray# RealWorld (Unlifted a)
-> State# RealWorld
-> (# State# RealWorld, SmallUnliftedArray# (Unlifted a) #)
forall s (a :: TYPE 'UnliftedRep).
SmallMutableUnliftedArray# s a
-> State# s -> (# State# s, SmallUnliftedArray# a #)
unsafeFreezeSmallUnliftedArray# SmallMutableUnliftedArray# RealWorld (Unlifted a)
mary# State# RealWorld
s'} of (# State# RealWorld
_, SmallUnliftedArray# (Unlifted a)
ary# #) -> SmallUnliftedArray# (Unlifted a)
ary#
{-# INLINE dupableRunSmallUnliftedArray# #-}

unST :: ST s a -> State# s -> (# State# s, a #)
unST :: ST s a -> State# s -> (# State# s, a #)
unST (ST State# s -> (# State# s, a #)
f) = State# s -> (# State# s, a #)
f

unsafeCreateSmallUnliftedArray
  :: Int
  -> (forall s. SmallMutableUnliftedArray s a -> ST s ())
  -> SmallUnliftedArray a
unsafeCreateSmallUnliftedArray :: Int
-> (forall s. SmallMutableUnliftedArray s a -> ST s ())
-> SmallUnliftedArray a
unsafeCreateSmallUnliftedArray !Int
n forall s. SmallMutableUnliftedArray s a -> ST s ()
f = (forall s. ST s (SmallMutableUnliftedArray s a))
-> SmallUnliftedArray a
forall a.
(forall s. ST s (SmallMutableUnliftedArray s a))
-> SmallUnliftedArray a
runSmallUnliftedArray ((forall s. ST s (SmallMutableUnliftedArray s a))
 -> SmallUnliftedArray a)
-> (forall s. ST s (SmallMutableUnliftedArray s a))
-> SmallUnliftedArray a
forall a b. (a -> b) -> a -> b
$ do
  SmallMutableUnliftedArray s a
mary <- Int -> ST s (SmallMutableUnliftedArray s a)
forall s a. Int -> ST s (SmallMutableUnliftedArray s a)
unsafeNewSmallUnliftedArray Int
n
  SmallMutableUnliftedArray s a -> ST s ()
forall s. SmallMutableUnliftedArray s a -> ST s ()
f SmallMutableUnliftedArray s a
mary
  SmallMutableUnliftedArray s a
-> ST s (SmallMutableUnliftedArray s a)
forall (f :: * -> *) a. Applicative f => a -> f a
pure SmallMutableUnliftedArray s a
mary

-- | Creates a new 'MutableUnliftedArray'. This function is unsafe because it
-- initializes all elements of the array as pointers to the empty array. Attempting
-- to read one of these elements before writing to it is in effect an unsafe
-- coercion from @'UnliftedArray' a@ to the element type.
unsafeNewSmallUnliftedArray
  :: Int -- ^ size
  -> ST s (SmallMutableUnliftedArray s a)
{-# inline unsafeNewSmallUnliftedArray #-}
unsafeNewSmallUnliftedArray :: Int -> ST s (SmallMutableUnliftedArray s a)
unsafeNewSmallUnliftedArray (I# Int#
i) = STRep s (SmallMutableUnliftedArray s a)
-> ST s (SmallMutableUnliftedArray s a)
forall s a. STRep s a -> ST s a
ST (STRep s (SmallMutableUnliftedArray s a)
 -> ST s (SmallMutableUnliftedArray s a))
-> STRep s (SmallMutableUnliftedArray s a)
-> ST s (SmallMutableUnliftedArray s a)
forall a b. (a -> b) -> a -> b
$ \State# s
s -> case Int#
-> State# s
-> (# State# s, SmallMutableUnliftedArray# s (Unlifted a) #)
forall s (a :: TYPE 'UnliftedRep).
Int# -> State# s -> (# State# s, SmallMutableUnliftedArray# s a #)
unsafeNewSmallUnliftedArray# Int#
i State# s
s of
  (# State# s
s', SmallMutableUnliftedArray# s (Unlifted a)
ma #) -> (# State# s
s', SmallMutableUnliftedArray# s (Unlifted a)
-> SmallMutableUnliftedArray s a
forall s a (unlifted_a :: TYPE 'UnliftedRep).
SmallMutableUnliftedArray# s unlifted_a
-> SmallMutableUnliftedArray_ s a unlifted_a
SmallMutableUnliftedArray SmallMutableUnliftedArray# s (Unlifted a)
ma #)


-- | Creates a copy of a portion of a 'SmallUnliftedArray'
cloneSmallUnliftedArray
  :: SmallUnliftedArray a -- ^ source
  -> Int -- ^ offset
  -> Int -- ^ length
  -> SmallUnliftedArray a
{-# inline cloneSmallUnliftedArray #-}
cloneSmallUnliftedArray :: SmallUnliftedArray a -> Int -> Int -> SmallUnliftedArray a
cloneSmallUnliftedArray (SmallUnliftedArray SmallUnliftedArray# (Unlifted a)
ary) (I# Int#
off) (I# Int#
len)
  = SmallUnliftedArray# (Unlifted a) -> SmallUnliftedArray a
forall a (unlifted_a :: TYPE 'UnliftedRep).
SmallUnliftedArray# unlifted_a -> SmallUnliftedArray_ a unlifted_a
SmallUnliftedArray (SmallUnliftedArray# (Unlifted a)
-> Int# -> Int# -> SmallUnliftedArray# (Unlifted a)
forall (a :: TYPE 'UnliftedRep).
SmallUnliftedArray# a -> Int# -> Int# -> SmallUnliftedArray# a
cloneSmallUnliftedArray# SmallUnliftedArray# (Unlifted a)
ary Int#
off Int#
len)

-- | Creates a new 'MutableUnliftedArray' containing a copy of a portion of
-- another mutable array.
cloneSmallMutableUnliftedArray
  :: SmallMutableUnliftedArray s a -- ^ source
  -> Int -- ^ offset
  -> Int -- ^ length
  -> ST s (SmallMutableUnliftedArray s a)
{-# inline cloneSmallMutableUnliftedArray #-}
cloneSmallMutableUnliftedArray :: SmallMutableUnliftedArray s a
-> Int -> Int -> ST s (SmallMutableUnliftedArray s a)
cloneSmallMutableUnliftedArray (SmallMutableUnliftedArray SmallMutableUnliftedArray# s (Unlifted a)
mary) (I# Int#
off) (I# Int#
len)
  = STRep s (SmallMutableUnliftedArray s a)
-> ST s (SmallMutableUnliftedArray s a)
forall s a. STRep s a -> ST s a
ST (STRep s (SmallMutableUnliftedArray s a)
 -> ST s (SmallMutableUnliftedArray s a))
-> STRep s (SmallMutableUnliftedArray s a)
-> ST s (SmallMutableUnliftedArray s a)
forall a b. (a -> b) -> a -> b
$ \State# s
s -> case SmallMutableUnliftedArray# s (Unlifted a)
-> Int#
-> Int#
-> State# s
-> (# State# s, SmallMutableUnliftedArray# s (Unlifted a) #)
forall s (a :: TYPE 'UnliftedRep).
SmallMutableUnliftedArray# s a
-> Int#
-> Int#
-> State# s
-> (# State# s, SmallMutableUnliftedArray# s a #)
cloneSmallMutableUnliftedArray# SmallMutableUnliftedArray# s (Unlifted a)
mary Int#
off Int#
len State# s
s of
      (# State# s
s', SmallMutableUnliftedArray# s (Unlifted a)
mary' #) -> (# State# s
s', SmallMutableUnliftedArray# s (Unlifted a)
-> SmallMutableUnliftedArray s a
forall s a (unlifted_a :: TYPE 'UnliftedRep).
SmallMutableUnliftedArray# s unlifted_a
-> SmallMutableUnliftedArray_ s a unlifted_a
SmallMutableUnliftedArray SmallMutableUnliftedArray# s (Unlifted a)
mary' #)

emptySmallUnliftedArray :: SmallUnliftedArray a
emptySmallUnliftedArray :: SmallUnliftedArray a
emptySmallUnliftedArray = SmallUnliftedArray# (Unlifted a) -> SmallUnliftedArray a
forall a (unlifted_a :: TYPE 'UnliftedRep).
SmallUnliftedArray# unlifted_a -> SmallUnliftedArray_ a unlifted_a
SmallUnliftedArray ((# #) -> SmallUnliftedArray# (Unlifted a)
forall (a :: TYPE 'UnliftedRep). (# #) -> SmallUnliftedArray# a
emptySmallUnliftedArray# (##))

singletonSmallUnliftedArray :: PrimUnlifted a => a -> SmallUnliftedArray a
{-# INLINE singletonSmallUnliftedArray #-}
singletonSmallUnliftedArray :: a -> SmallUnliftedArray a
singletonSmallUnliftedArray a
x = (forall s. ST s (SmallMutableUnliftedArray s a))
-> SmallUnliftedArray a
forall a.
(forall s. ST s (SmallMutableUnliftedArray s a))
-> SmallUnliftedArray a
runSmallUnliftedArray ((forall s. ST s (SmallMutableUnliftedArray s a))
 -> SmallUnliftedArray a)
-> (forall s. ST s (SmallMutableUnliftedArray s a))
-> SmallUnliftedArray a
forall a b. (a -> b) -> a -> b
$ Int -> a -> ST s (SmallMutableUnliftedArray s a)
forall a s.
PrimUnlifted a =>
Int -> a -> ST s (SmallMutableUnliftedArray s a)
newSmallUnliftedArray Int
1 a
x

concatSmallUnliftedArray :: SmallUnliftedArray a -> SmallUnliftedArray a -> SmallUnliftedArray a
{-# INLINE concatSmallUnliftedArray #-}
concatSmallUnliftedArray :: SmallUnliftedArray a
-> SmallUnliftedArray a -> SmallUnliftedArray a
concatSmallUnliftedArray (SmallUnliftedArray SmallUnliftedArray# (Unlifted a)
a1) (SmallUnliftedArray SmallUnliftedArray# (Unlifted a)
a2)
  = SmallUnliftedArray# (Unlifted a) -> SmallUnliftedArray a
forall a (unlifted_a :: TYPE 'UnliftedRep).
SmallUnliftedArray# unlifted_a -> SmallUnliftedArray_ a unlifted_a
SmallUnliftedArray (SmallUnliftedArray# (Unlifted a)
-> SmallUnliftedArray# (Unlifted a)
-> SmallUnliftedArray# (Unlifted a)
forall (a :: TYPE 'UnliftedRep).
SmallUnliftedArray# a
-> SmallUnliftedArray# a -> SmallUnliftedArray# a
concatSmallUnliftedArray# SmallUnliftedArray# (Unlifted a)
a1 SmallUnliftedArray# (Unlifted a)
a2)

-- This junk is to make sure we unbox properly. Inlining this doesn't seem
-- likely to be much of a win ever, and could potentially lead to reboxing,
-- so we NOINLINE. It would be nice to find a prettier way to do this.
concatSmallUnliftedArray# :: SmallUnliftedArray# a -> SmallUnliftedArray# a -> SmallUnliftedArray# a
{-# NOINLINE concatSmallUnliftedArray# #-}
concatSmallUnliftedArray# :: SmallUnliftedArray# a
-> SmallUnliftedArray# a -> SmallUnliftedArray# a
concatSmallUnliftedArray# SmallUnliftedArray# a
a1 SmallUnliftedArray# a
a2 =
  let !sza1 :: Int#
sza1 = SmallUnliftedArray# a -> Int#
forall (a :: TYPE 'UnliftedRep). SmallUnliftedArray# a -> Int#
sizeofSmallUnliftedArray# SmallUnliftedArray# a
a1
  in
    if Int# -> Bool
Exts.isTrue# (Int#
sza1 Int# -> Int# -> Int#
Exts.==# Int#
0#)
    then SmallUnliftedArray# a
a2
    else
      let !sza2 :: Int#
sza2 = SmallUnliftedArray# a -> Int#
forall (a :: TYPE 'UnliftedRep). SmallUnliftedArray# a -> Int#
sizeofSmallUnliftedArray# SmallUnliftedArray# a
a2
      in
        if Int# -> Bool
Exts.isTrue# (Int#
sza2 Int# -> Int# -> Int#
Exts.==# Int#
0#)
        then SmallUnliftedArray# a
a1
        else (State# RealWorld -> SmallUnliftedArray# a)
-> SmallUnliftedArray# a
forall o. (State# RealWorld -> o) -> o
Exts.runRW# ((State# RealWorld -> SmallUnliftedArray# a)
 -> SmallUnliftedArray# a)
-> (State# RealWorld -> SmallUnliftedArray# a)
-> SmallUnliftedArray# a
forall a b. (a -> b) -> a -> b
$ \State# RealWorld
s0 ->
          let
            finish :: State# RealWorld -> SmallUnliftedArray# a
finish State# RealWorld
s =
              case Int#
-> State# RealWorld
-> (# State# RealWorld, SmallMutableUnliftedArray# RealWorld a #)
forall s (a :: TYPE 'UnliftedRep).
Int# -> State# s -> (# State# s, SmallMutableUnliftedArray# s a #)
unsafeNewSmallUnliftedArray# (Int#
sza1 Int# -> Int# -> Int#
Exts.+# Int#
sza2) State# RealWorld
s of { (# State# RealWorld
s', SmallMutableUnliftedArray# RealWorld a
ma #) ->
              case SmallUnliftedArray# a
-> Int#
-> SmallMutableUnliftedArray# RealWorld a
-> Int#
-> Int#
-> State# RealWorld
-> State# RealWorld
forall (a :: TYPE 'UnliftedRep) s.
SmallUnliftedArray# a
-> Int#
-> SmallMutableUnliftedArray# s a
-> Int#
-> Int#
-> State# s
-> State# s
copySmallUnliftedArray# SmallUnliftedArray# a
a1 Int#
0# SmallMutableUnliftedArray# RealWorld a
ma Int#
0# Int#
sza1 State# RealWorld
s' of { State# RealWorld
s'' ->
              case SmallUnliftedArray# a
-> Int#
-> SmallMutableUnliftedArray# RealWorld a
-> Int#
-> Int#
-> State# RealWorld
-> State# RealWorld
forall (a :: TYPE 'UnliftedRep) s.
SmallUnliftedArray# a
-> Int#
-> SmallMutableUnliftedArray# s a
-> Int#
-> Int#
-> State# s
-> State# s
copySmallUnliftedArray# SmallUnliftedArray# a
a2 Int#
0# SmallMutableUnliftedArray# RealWorld a
ma Int#
sza1 Int#
sza2 State# RealWorld
s'' of { State# RealWorld
s''' ->
              case SmallMutableUnliftedArray# RealWorld a
-> State# RealWorld
-> (# State# RealWorld, SmallUnliftedArray# a #)
forall s (a :: TYPE 'UnliftedRep).
SmallMutableUnliftedArray# s a
-> State# s -> (# State# s, SmallUnliftedArray# a #)
unsafeFreezeSmallUnliftedArray# SmallMutableUnliftedArray# RealWorld a
ma State# RealWorld
s''' of
                (# State# RealWorld
_, SmallUnliftedArray# a
ar #) -> SmallUnliftedArray# a
ar}}}
            -- GHC wants to inline this, but I very much doubt it's worth the
            -- extra code, considering that it calls multiple out-of-line
            -- primops.
            {-# NOINLINE finish #-}
          in
            -- When the final array will be "small", we tolerate the possibility that
            -- it could be constructed multiple times in different threads. Currently,
            -- "small" means fewer than 1000 elements. This is a totally arbitrary
            -- cutoff that has not been tuned whatsoever.
            if Int# -> Bool
Exts.isTrue# ((Int#
sza1 Int# -> Int# -> Int#
Exts.+# Int#
sza2) Int# -> Int# -> Int#
Exts.>=# Int#
1000#)
            then State# RealWorld -> SmallUnliftedArray# a
finish (State# RealWorld -> State# RealWorld
forall d. State# d -> State# d
Exts.noDuplicate# State# RealWorld
s0)
            else State# RealWorld -> SmallUnliftedArray# a
finish State# RealWorld
s0

foldrSmallUnliftedArray :: forall a b. PrimUnlifted a => (a -> b -> b) -> b -> SmallUnliftedArray a -> b
{-# INLINE foldrSmallUnliftedArray #-}
foldrSmallUnliftedArray :: (a -> b -> b) -> b -> SmallUnliftedArray a -> b
foldrSmallUnliftedArray a -> b -> b
f b
z SmallUnliftedArray a
arr = Int -> b
go Int
0
  where
    !sz :: Int
sz = SmallUnliftedArray a -> Int
forall e. SmallUnliftedArray e -> Int
sizeofSmallUnliftedArray SmallUnliftedArray a
arr
    go :: Int -> b
go !Int
i
      | Int
sz Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
i = a -> b -> b
f (SmallUnliftedArray a -> Int -> a
forall a. PrimUnlifted a => SmallUnliftedArray a -> Int -> a
indexSmallUnliftedArray SmallUnliftedArray a
arr Int
i) (Int -> b
go (Int
iInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
1))
      | Bool
otherwise = b
z

-- | Strict right-associated fold over the elements of an 'SmallUnliftedArray.
{-# INLINE foldrSmallUnliftedArray' #-}
foldrSmallUnliftedArray' :: forall a b. PrimUnlifted a => (a -> b -> b) -> b -> SmallUnliftedArray a -> b
foldrSmallUnliftedArray' :: (a -> b -> b) -> b -> SmallUnliftedArray a -> b
foldrSmallUnliftedArray' a -> b -> b
f b
z0 SmallUnliftedArray a
arr = Int -> b -> b
go (SmallUnliftedArray a -> Int
forall e. SmallUnliftedArray e -> Int
sizeofSmallUnliftedArray SmallUnliftedArray a
arr Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1) b
z0
  where
    go :: Int -> b -> b
go !Int
i !b
acc
      | Int
i Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
0 = b
acc
      | Bool
otherwise = Int -> b -> b
go (Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1) (a -> b -> b
f (SmallUnliftedArray a -> Int -> a
forall a. PrimUnlifted a => SmallUnliftedArray a -> Int -> a
indexSmallUnliftedArray SmallUnliftedArray a
arr Int
i) b
acc)

-- | Lazy left-associated fold over the elements of an 'SmallUnliftedArray'.
{-# INLINE foldlSmallUnliftedArray #-}
foldlSmallUnliftedArray :: forall a b. PrimUnlifted a => (b -> a -> b) -> b -> SmallUnliftedArray a -> b
foldlSmallUnliftedArray :: (b -> a -> b) -> b -> SmallUnliftedArray a -> b
foldlSmallUnliftedArray b -> a -> b
f b
z SmallUnliftedArray a
arr = Int -> b
go (SmallUnliftedArray a -> Int
forall e. SmallUnliftedArray e -> Int
sizeofSmallUnliftedArray SmallUnliftedArray a
arr Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1)
  where
    go :: Int -> b
go !Int
i
      | Int
i Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
0 = b
z
      | Bool
otherwise = b -> a -> b
f (Int -> b
go (Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1)) (SmallUnliftedArray a -> Int -> a
forall a. PrimUnlifted a => SmallUnliftedArray a -> Int -> a
indexSmallUnliftedArray SmallUnliftedArray a
arr Int
i)

-- | Strict left-associated fold over the elements of an 'SmallUnliftedArray'.
{-# INLINE foldlSmallUnliftedArray' #-}
foldlSmallUnliftedArray' :: forall a b. PrimUnlifted a => (b -> a -> b) -> b -> SmallUnliftedArray a -> b
foldlSmallUnliftedArray' :: (b -> a -> b) -> b -> SmallUnliftedArray a -> b
foldlSmallUnliftedArray' b -> a -> b
f b
z0 SmallUnliftedArray a
arr = Int -> b -> b
go Int
0 b
z0
  where
    !sz :: Int
sz = SmallUnliftedArray a -> Int
forall e. SmallUnliftedArray e -> Int
sizeofSmallUnliftedArray SmallUnliftedArray a
arr
    go :: Int -> b -> b
go !Int
i !b
acc
      | Int
i Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
sz = Int -> b -> b
go (Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1) (b -> a -> b
f b
acc (SmallUnliftedArray a -> Int -> a
forall a. PrimUnlifted a => SmallUnliftedArray a -> Int -> a
indexSmallUnliftedArray SmallUnliftedArray a
arr Int
i))
      | Bool
otherwise = b
acc

-- | Strict effectful left-associated fold over the elements of an 'SmallUnliftedArray'.
{-# INLINE foldlSmallUnliftedArrayM' #-}
foldlSmallUnliftedArrayM' :: (PrimUnlifted a, Monad m)
  => (b -> a -> m b) -> b -> SmallUnliftedArray a -> m b
foldlSmallUnliftedArrayM' :: (b -> a -> m b) -> b -> SmallUnliftedArray a -> m b
foldlSmallUnliftedArrayM' b -> a -> m b
f b
z0 SmallUnliftedArray a
arr = Int -> b -> m b
go Int
0 b
z0
  where
    !sz :: Int
sz = SmallUnliftedArray a -> Int
forall e. SmallUnliftedArray e -> Int
sizeofSmallUnliftedArray SmallUnliftedArray a
arr
    go :: Int -> b -> m b
go !Int
i !b
acc
      | Int
i Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
sz = b -> a -> m b
f b
acc (SmallUnliftedArray a -> Int -> a
forall a. PrimUnlifted a => SmallUnliftedArray a -> Int -> a
indexSmallUnliftedArray SmallUnliftedArray a
arr Int
i) m b -> (b -> m b) -> m b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Int -> b -> m b
go (Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1) 
      | Bool
otherwise = b -> m b
forall (f :: * -> *) a. Applicative f => a -> f a
pure b
acc

-- | Effectfully traverse the elements of an 'SmallUnliftedArray', discarding
-- the resulting values.
{-# INLINE traverseSmallUnliftedArray_ #-}
traverseSmallUnliftedArray_ :: (PrimUnlifted a, Applicative m)
  => (a -> m b) -> SmallUnliftedArray a -> m ()
traverseSmallUnliftedArray_ :: (a -> m b) -> SmallUnliftedArray a -> m ()
traverseSmallUnliftedArray_ a -> m b
f SmallUnliftedArray a
arr = Int -> m ()
go Int
0
  where
    !sz :: Int
sz = SmallUnliftedArray a -> Int
forall e. SmallUnliftedArray e -> Int
sizeofSmallUnliftedArray SmallUnliftedArray a
arr
    go :: Int -> m ()
go !Int
i
      | Int
i Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
sz = a -> m b
f (SmallUnliftedArray a -> Int -> a
forall a. PrimUnlifted a => SmallUnliftedArray a -> Int -> a
indexSmallUnliftedArray SmallUnliftedArray a
arr Int
i) m b -> m () -> m ()
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> Int -> m ()
go (Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1) 
      | Bool
otherwise = () -> m ()
forall (f :: * -> *) a. Applicative f => a -> f a
pure ()

-- | Effectful indexed traversal of the elements of an 'SmallUnliftedArray',
-- discarding the resulting values.
{-# INLINE itraverseSmallUnliftedArray_ #-}
itraverseSmallUnliftedArray_ :: (PrimUnlifted a, Applicative m)
  => (Int -> a -> m b) -> SmallUnliftedArray a -> m ()
itraverseSmallUnliftedArray_ :: (Int -> a -> m b) -> SmallUnliftedArray a -> m ()
itraverseSmallUnliftedArray_ Int -> a -> m b
f SmallUnliftedArray a
arr = Int -> m ()
go Int
0
  where
    !sz :: Int
sz = SmallUnliftedArray a -> Int
forall e. SmallUnliftedArray e -> Int
sizeofSmallUnliftedArray SmallUnliftedArray a
arr
    go :: Int -> m ()
go !Int
i
      | Int
i Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
sz = Int -> a -> m b
f Int
i (SmallUnliftedArray a -> Int -> a
forall a. PrimUnlifted a => SmallUnliftedArray a -> Int -> a
indexSmallUnliftedArray SmallUnliftedArray a
arr Int
i) m b -> m () -> m ()
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> Int -> m ()
go (Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1) 
      | Bool
otherwise = () -> m ()
forall (f :: * -> *) a. Applicative f => a -> f a
pure ()

-- | Map over the elements of an 'SmallUnliftedArray'.
{-# INLINE mapSmallUnliftedArray #-}
mapSmallUnliftedArray :: (PrimUnlifted a, PrimUnlifted b)
  => (a -> b)
  -> SmallUnliftedArray a
  -> SmallUnliftedArray b
-- See Data.Primitive.Unlifted.Array.ST for discussion of the noDuplicate#
-- buried in this unsafeCreateSmallUnliftedArray.
mapSmallUnliftedArray :: (a -> b) -> SmallUnliftedArray a -> SmallUnliftedArray b
mapSmallUnliftedArray a -> b
f SmallUnliftedArray a
arr = Int
-> (forall s. SmallMutableUnliftedArray s b -> ST s ())
-> SmallUnliftedArray b
forall a.
Int
-> (forall s. SmallMutableUnliftedArray s a -> ST s ())
-> SmallUnliftedArray a
unsafeCreateSmallUnliftedArray Int
sz ((forall s. SmallMutableUnliftedArray s b -> ST s ())
 -> SmallUnliftedArray b)
-> (forall s. SmallMutableUnliftedArray s b -> ST s ())
-> SmallUnliftedArray b
forall a b. (a -> b) -> a -> b
$ \SmallMutableUnliftedArray s b
marr -> do
  let go :: Int -> ST s ()
go !Int
ix = if Int
ix Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
sz
        then do
          let b :: b
b = a -> b
f (SmallUnliftedArray a -> Int -> a
forall a. PrimUnlifted a => SmallUnliftedArray a -> Int -> a
indexSmallUnliftedArray SmallUnliftedArray a
arr Int
ix)
          SmallMutableUnliftedArray s b -> Int -> b -> ST s ()
forall a s.
PrimUnlifted a =>
SmallMutableUnliftedArray s a -> Int -> a -> ST s ()
writeSmallUnliftedArray SmallMutableUnliftedArray s b
marr Int
ix b
b
          Int -> ST s ()
go (Int
ix Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1)
        else () -> ST s ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
  Int -> ST s ()
go Int
0
  where
  !sz :: Int
sz = SmallUnliftedArray a -> Int
forall e. SmallUnliftedArray e -> Int
sizeofSmallUnliftedArray SmallUnliftedArray a
arr

-- | Convert the unlifted array to a list.
{-# INLINE smallUnliftedArrayToList #-}
smallUnliftedArrayToList :: PrimUnlifted a => SmallUnliftedArray a -> [a]
smallUnliftedArrayToList :: SmallUnliftedArray a -> [a]
smallUnliftedArrayToList SmallUnliftedArray a
xs = (forall b. (a -> b -> b) -> b -> b) -> [a]
forall a. (forall b. (a -> b -> b) -> b -> b) -> [a]
Exts.build (\a -> b -> b
c b
n -> (a -> b -> b) -> b -> SmallUnliftedArray a -> b
forall a b.
PrimUnlifted a =>
(a -> b -> b) -> b -> SmallUnliftedArray a -> b
foldrSmallUnliftedArray a -> b -> b
c b
n SmallUnliftedArray a
xs)

smallUnliftedArrayFromList :: PrimUnlifted a => [a] -> SmallUnliftedArray a
smallUnliftedArrayFromList :: [a] -> SmallUnliftedArray a
smallUnliftedArrayFromList [a]
xs = Int -> [a] -> SmallUnliftedArray a
forall a. PrimUnlifted a => Int -> [a] -> SmallUnliftedArray a
smallUnliftedArrayFromListN ([a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
L.length [a]
xs) [a]
xs

smallUnliftedArrayFromListN :: forall a. PrimUnlifted a => Int -> [a] -> SmallUnliftedArray a
smallUnliftedArrayFromListN :: Int -> [a] -> SmallUnliftedArray a
smallUnliftedArrayFromListN Int
len [a]
vs = Int
-> (forall s. SmallMutableUnliftedArray s a -> ST s ())
-> SmallUnliftedArray a
forall a.
Int
-> (forall s. SmallMutableUnliftedArray s a -> ST s ())
-> SmallUnliftedArray a
unsafeCreateSmallUnliftedArray Int
len forall s. SmallMutableUnliftedArray s a -> ST s ()
run where
  run :: forall s. SmallMutableUnliftedArray s a -> ST s ()
  run :: SmallMutableUnliftedArray s a -> ST s ()
run SmallMutableUnliftedArray s a
arr = do
    let go :: [a] -> Int -> ST s ()
        go :: [a] -> Int -> ST s ()
go [] !Int
ix = if Int
ix Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
len
          -- The size check is mandatory since failure to initialize all elements
          -- introduces the possibility of a segfault happening when someone attempts
          -- to read the unitialized element. See the docs for unsafeNewSmallUnliftedArray.
          then () -> ST s ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
          else String -> String -> ST s ()
forall a. String -> String -> a
die String
"unliftedArrayFromListN" String
"list length less than specified size"
        go (a
a : [a]
as) !Int
ix = if Int
ix Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
len
          then do
            SmallMutableUnliftedArray s a -> Int -> a -> ST s ()
forall a s.
PrimUnlifted a =>
SmallMutableUnliftedArray s a -> Int -> a -> ST s ()
writeSmallUnliftedArray SmallMutableUnliftedArray s a
arr Int
ix a
a
            [a] -> Int -> ST s ()
go [a]
as (Int
ix Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1)
          else String -> String -> ST s ()
forall a. String -> String -> a
die String
"unliftedArrayFromListN" String
"list length greater than specified size"
    [a] -> Int -> ST s ()
go [a]
vs Int
0

instance (PrimUnlifted a, unlifted_a ~ Unlifted a)
  => Exts.IsList (SmallUnliftedArray_ a unlifted_a) where
  type Item (SmallUnliftedArray_ a _) = a
  fromList :: [Item (SmallUnliftedArray_ a unlifted_a)]
-> SmallUnliftedArray_ a unlifted_a
fromList = [Item (SmallUnliftedArray_ a unlifted_a)]
-> SmallUnliftedArray_ a unlifted_a
forall a. PrimUnlifted a => [a] -> SmallUnliftedArray a
smallUnliftedArrayFromList
  fromListN :: Int
-> [Item (SmallUnliftedArray_ a unlifted_a)]
-> SmallUnliftedArray_ a unlifted_a
fromListN = Int
-> [Item (SmallUnliftedArray_ a unlifted_a)]
-> SmallUnliftedArray_ a unlifted_a
forall a. PrimUnlifted a => Int -> [a] -> SmallUnliftedArray a
smallUnliftedArrayFromListN
  toList :: SmallUnliftedArray_ a unlifted_a
-> [Item (SmallUnliftedArray_ a unlifted_a)]
toList = SmallUnliftedArray_ a unlifted_a
-> [Item (SmallUnliftedArray_ a unlifted_a)]
forall a. PrimUnlifted a => SmallUnliftedArray a -> [a]
smallUnliftedArrayToList

instance (PrimUnlifted a, unlifted_a ~ Unlifted a)
  => Semigroup (SmallUnliftedArray_ a unlifted_a) where
  <> :: SmallUnliftedArray_ a unlifted_a
-> SmallUnliftedArray_ a unlifted_a
-> SmallUnliftedArray_ a unlifted_a
(<>) = SmallUnliftedArray_ a unlifted_a
-> SmallUnliftedArray_ a unlifted_a
-> SmallUnliftedArray_ a unlifted_a
forall a.
SmallUnliftedArray a
-> SmallUnliftedArray a -> SmallUnliftedArray a
concatSmallUnliftedArray

instance (PrimUnlifted a, unlifted_a ~ Unlifted a) => Monoid (SmallUnliftedArray_ a unlifted_a) where
  mempty :: SmallUnliftedArray_ a unlifted_a
mempty = SmallUnliftedArray_ a unlifted_a
forall a. SmallUnliftedArray a
emptySmallUnliftedArray

instance (Show a, PrimUnlifted a, unlifted_a ~ Unlifted a) => Show (SmallUnliftedArray_ a unlifted_a) where
  showsPrec :: Int -> SmallUnliftedArray_ a unlifted_a -> ShowS
showsPrec Int
p SmallUnliftedArray_ a unlifted_a
a = Bool -> ShowS -> ShowS
showParen (Int
p Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
10) (ShowS -> ShowS) -> ShowS -> ShowS
forall a b. (a -> b) -> a -> b
$
    String -> ShowS
showString String
"fromListN " ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> ShowS
forall a. Show a => a -> ShowS
shows (SmallUnliftedArray a -> Int
forall e. SmallUnliftedArray e -> Int
sizeofSmallUnliftedArray SmallUnliftedArray_ a unlifted_a
SmallUnliftedArray a
a) ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> ShowS
showString String
" "
      ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [a] -> ShowS
forall a. Show a => a -> ShowS
shows (SmallUnliftedArray a -> [a]
forall a. PrimUnlifted a => SmallUnliftedArray a -> [a]
smallUnliftedArrayToList SmallUnliftedArray_ a unlifted_a
SmallUnliftedArray a
a)

instance unlifted_a ~ Unlifted a => Eq (SmallMutableUnliftedArray_ s a unlifted_a) where
  == :: SmallMutableUnliftedArray_ s a unlifted_a
-> SmallMutableUnliftedArray_ s a unlifted_a -> Bool
(==) = SmallMutableUnliftedArray_ s a unlifted_a
-> SmallMutableUnliftedArray_ s a unlifted_a -> Bool
forall s a.
SmallMutableUnliftedArray s a
-> SmallMutableUnliftedArray s a -> Bool
sameSmallMutableUnliftedArray

instance (Eq a, PrimUnlifted a, unlifted_a ~ Unlifted a) => Eq (SmallUnliftedArray_ a unlifted_a) where
  SmallUnliftedArray_ a unlifted_a
aa1 == :: SmallUnliftedArray_ a unlifted_a
-> SmallUnliftedArray_ a unlifted_a -> Bool
== SmallUnliftedArray_ a unlifted_a
aa2 = SmallUnliftedArray a -> Int
forall e. SmallUnliftedArray e -> Int
sizeofSmallUnliftedArray SmallUnliftedArray_ a unlifted_a
SmallUnliftedArray a
aa1 Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== SmallUnliftedArray a -> Int
forall e. SmallUnliftedArray e -> Int
sizeofSmallUnliftedArray SmallUnliftedArray_ a unlifted_a
SmallUnliftedArray a
aa2
            Bool -> Bool -> Bool
&& Int -> Bool
loop (SmallUnliftedArray a -> Int
forall e. SmallUnliftedArray e -> Int
sizeofSmallUnliftedArray SmallUnliftedArray_ a unlifted_a
SmallUnliftedArray a
aa1 Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1)
   where
   loop :: Int -> Bool
loop Int
i
     | Int
i Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
0 = Bool
True
     | Bool
otherwise = SmallUnliftedArray a -> Int -> a
forall a. PrimUnlifted a => SmallUnliftedArray a -> Int -> a
indexSmallUnliftedArray SmallUnliftedArray_ a unlifted_a
SmallUnliftedArray a
aa1 Int
i a -> a -> Bool
forall a. Eq a => a -> a -> Bool
== SmallUnliftedArray a -> Int -> a
forall a. PrimUnlifted a => SmallUnliftedArray a -> Int -> a
indexSmallUnliftedArray SmallUnliftedArray_ a unlifted_a
SmallUnliftedArray a
aa2 Int
i Bool -> Bool -> Bool
&& Int -> Bool
loop (Int
iInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1)

die :: String -> String -> a
die :: String -> String -> a
die String
fun String
problem = String -> a
forall a. HasCallStack => String -> a
error (String -> a) -> String -> a
forall a b. (a -> b) -> a -> b
$ String
"Data.Primitive.Unlifted.SmallArray.ST." String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
fun String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
": " String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
problem