{-# LANGUAGE UnboxedTuples #-}
module Streamly.Internal.Data.Array.Mut.Type
(
Array (..)
, newArray
, writeNUnsafe
, writeN
, putIndex
, putIndexUnsafe
, modifyIndexUnsafe
, modifyIndex
, snocWith
, snoc
, snocUnsafe
, read
, toStreamD
, toStreamK
, toList
, producer
, getIndex
, getIndexUnsafe
, getSliceUnsafe
, getSlice
)
where
#include "inline.hs"
import Control.Exception (assert)
import Control.Monad.IO.Class (MonadIO(..))
import GHC.Base
( MutableArray#
, RealWorld
, copyMutableArray#
, newArray#
, readArray#
, writeArray#
)
import GHC.IO (IO(..))
import GHC.Int (Int(..))
import Streamly.Internal.Data.Fold.Type (Fold(..))
import Streamly.Internal.Data.Producer.Type (Producer (..))
import Streamly.Internal.Data.Unfold.Type (Unfold(..))
import qualified Streamly.Internal.Data.Fold.Type as FL
import qualified Streamly.Internal.Data.Producer as Producer
import qualified Streamly.Internal.Data.Stream.StreamD as D
import qualified Streamly.Internal.Data.Stream.StreamK as K
import Prelude hiding (read)
data Array a =
Array
{ forall a. Array a -> MutableArray# RealWorld a
arrContents# :: MutableArray# RealWorld a
, forall a. Array a -> Int
arrStart :: {-# UNPACK #-}!Int
, forall a. Array a -> Int
arrLen :: {-# UNPACK #-}!Int
, forall a. Array a -> Int
arrTrueLen :: {-# UNPACK #-}!Int
}
{-# INLINE bottomElement #-}
bottomElement :: a
bottomElement :: forall a. a
bottomElement =
forall a. HasCallStack => [Char] -> a
error
forall a b. (a -> b) -> a -> b
$ [[Char]] -> [Char]
unwords
[ [Char]
funcName
, [Char]
"This is the bottom element of the array."
, [Char]
"This is a place holder and should never be reached!"
]
where
funcName :: [Char]
funcName = [Char]
"Streamly.Internal.Data.Array.Mut.Type.bottomElement:"
{-# INLINE newArray #-}
newArray :: forall m a. MonadIO m => Int -> m (Array a)
newArray :: forall (m :: * -> *) a. MonadIO m => Int -> m (Array a)
newArray n :: Int
n@(I# Int#
n#) =
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO
forall a b. (a -> b) -> a -> b
$ forall a. (State# RealWorld -> (# State# RealWorld, a #)) -> IO a
IO
forall a b. (a -> b) -> a -> b
$ \State# RealWorld
s# ->
case forall a d.
Int# -> a -> State# d -> (# State# d, MutableArray# d a #)
newArray# Int#
n# forall a. a
bottomElement State# RealWorld
s# of
(# State# RealWorld
s1#, MutableArray# RealWorld a
arr# #) ->
let ma :: Array a
ma = forall a. MutableArray# RealWorld a -> Int -> Int -> Int -> Array a
Array MutableArray# RealWorld a
arr# Int
0 Int
0 Int
n
in (# State# RealWorld
s1#, Array a
ma #)
{-# INLINE putIndexUnsafe #-}
putIndexUnsafe :: forall m a. MonadIO m => Array a -> Int -> a -> m ()
putIndexUnsafe :: forall (m :: * -> *) a. MonadIO m => Array a -> Int -> a -> m ()
putIndexUnsafe Array {Int
MutableArray# RealWorld a
arrTrueLen :: Int
arrLen :: Int
arrStart :: Int
arrContents# :: MutableArray# RealWorld a
arrTrueLen :: forall a. Array a -> Int
arrLen :: forall a. Array a -> Int
arrStart :: forall a. Array a -> Int
arrContents# :: forall a. Array a -> MutableArray# RealWorld a
..} Int
i a
x =
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO
forall a b. (a -> b) -> a -> b
$ forall a. (State# RealWorld -> (# State# RealWorld, a #)) -> IO a
IO
forall a b. (a -> b) -> a -> b
$ \State# RealWorld
s# ->
case Int
i forall a. Num a => a -> a -> a
+ Int
arrStart of
I# Int#
n# ->
let s1# :: State# RealWorld
s1# = forall d a. MutableArray# d a -> Int# -> a -> State# d -> State# d
writeArray# MutableArray# RealWorld a
arrContents# Int#
n# a
x State# RealWorld
s#
in (# State# RealWorld
s1#, () #)
invalidIndex :: String -> Int -> a
invalidIndex :: forall a. [Char] -> Int -> a
invalidIndex [Char]
label Int
i =
forall a. HasCallStack => [Char] -> a
error forall a b. (a -> b) -> a -> b
$ [Char]
label forall a. [a] -> [a] -> [a]
++ [Char]
": invalid array index " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> [Char]
show Int
i
{-# INLINE putIndex #-}
putIndex :: MonadIO m => Array a -> Int -> a -> m ()
putIndex :: forall (m :: * -> *) a. MonadIO m => Array a -> Int -> a -> m ()
putIndex arr :: Array a
arr@Array {Int
MutableArray# RealWorld a
arrTrueLen :: Int
arrLen :: Int
arrStart :: Int
arrContents# :: MutableArray# RealWorld a
arrTrueLen :: forall a. Array a -> Int
arrLen :: forall a. Array a -> Int
arrStart :: forall a. Array a -> Int
arrContents# :: forall a. Array a -> MutableArray# RealWorld a
..} Int
i a
x =
if Int
i forall a. Ord a => a -> a -> Bool
>= Int
0 Bool -> Bool -> Bool
&& Int
i forall a. Ord a => a -> a -> Bool
< Int
arrLen
then forall (m :: * -> *) a. MonadIO m => Array a -> Int -> a -> m ()
putIndexUnsafe Array a
arr Int
i a
x
else forall a. [Char] -> Int -> a
invalidIndex [Char]
"putIndex" Int
i
modifyIndexUnsafe :: MonadIO m => Array a -> Int -> (a -> (a, b)) -> m b
modifyIndexUnsafe :: forall (m :: * -> *) a b.
MonadIO m =>
Array a -> Int -> (a -> (a, b)) -> m b
modifyIndexUnsafe Array {Int
MutableArray# RealWorld a
arrTrueLen :: Int
arrLen :: Int
arrStart :: Int
arrContents# :: MutableArray# RealWorld a
arrTrueLen :: forall a. Array a -> Int
arrLen :: forall a. Array a -> Int
arrStart :: forall a. Array a -> Int
arrContents# :: forall a. Array a -> MutableArray# RealWorld a
..} Int
i a -> (a, b)
f = do
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO
forall a b. (a -> b) -> a -> b
$ forall a. (State# RealWorld -> (# State# RealWorld, a #)) -> IO a
IO
forall a b. (a -> b) -> a -> b
$ \State# RealWorld
s# ->
case Int
i forall a. Num a => a -> a -> a
+ Int
arrStart of
I# Int#
n# ->
case forall d a.
MutableArray# d a -> Int# -> State# d -> (# State# d, a #)
readArray# MutableArray# RealWorld a
arrContents# Int#
n# State# RealWorld
s# of
(# State# RealWorld
s1#, a
a #) ->
let (a
a1, b
b) = a -> (a, b)
f a
a
s2# :: State# RealWorld
s2# = forall d a. MutableArray# d a -> Int# -> a -> State# d -> State# d
writeArray# MutableArray# RealWorld a
arrContents# Int#
n# a
a1 State# RealWorld
s1#
in (# State# RealWorld
s2#, b
b #)
modifyIndex :: MonadIO m => Array a -> Int -> (a -> (a, b)) -> m b
modifyIndex :: forall (m :: * -> *) a b.
MonadIO m =>
Array a -> Int -> (a -> (a, b)) -> m b
modifyIndex arr :: Array a
arr@Array {Int
MutableArray# RealWorld a
arrTrueLen :: Int
arrLen :: Int
arrStart :: Int
arrContents# :: MutableArray# RealWorld a
arrTrueLen :: forall a. Array a -> Int
arrLen :: forall a. Array a -> Int
arrStart :: forall a. Array a -> Int
arrContents# :: forall a. Array a -> MutableArray# RealWorld a
..} Int
i a -> (a, b)
f = do
if Int
i forall a. Ord a => a -> a -> Bool
>= Int
0 Bool -> Bool -> Bool
&& Int
i forall a. Ord a => a -> a -> Bool
< Int
arrLen
then forall (m :: * -> *) a b.
MonadIO m =>
Array a -> Int -> (a -> (a, b)) -> m b
modifyIndexUnsafe Array a
arr Int
i a -> (a, b)
f
else forall a. [Char] -> Int -> a
invalidIndex [Char]
"modifyIndex" Int
i
realloc :: MonadIO m => Int -> Array a -> m (Array a)
realloc :: forall (m :: * -> *) a. MonadIO m => Int -> Array a -> m (Array a)
realloc Int
n Array a
arr = do
Array a
arr1 <- forall (m :: * -> *) a. MonadIO m => Int -> m (Array a)
newArray Int
n
let !newLen :: Int
newLen@(I# Int#
newLen#) = forall a. Ord a => a -> a -> a
min Int
n (forall a. Array a -> Int
arrLen Array a
arr)
!(I# Int#
arrS#) = forall a. Array a -> Int
arrStart Array a
arr
!(I# Int#
arr1S#) = forall a. Array a -> Int
arrStart Array a
arr1
arrC# :: MutableArray# RealWorld a
arrC# = forall a. Array a -> MutableArray# RealWorld a
arrContents# Array a
arr
arr1C# :: MutableArray# RealWorld a
arr1C# = forall a. Array a -> MutableArray# RealWorld a
arrContents# Array a
arr1
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO
forall a b. (a -> b) -> a -> b
$ forall a. (State# RealWorld -> (# State# RealWorld, a #)) -> IO a
IO
forall a b. (a -> b) -> a -> b
$ \State# RealWorld
s# ->
let s1# :: State# RealWorld
s1# = forall d a.
MutableArray# d a
-> Int#
-> MutableArray# d a
-> Int#
-> Int#
-> State# d
-> State# d
copyMutableArray# MutableArray# RealWorld a
arrC# Int#
arrS# MutableArray# RealWorld a
arr1C# Int#
arr1S# Int#
newLen# State# RealWorld
s#
in (# State# RealWorld
s1#, Array a
arr1 {arrLen :: Int
arrLen = Int
newLen, arrTrueLen :: Int
arrTrueLen = Int
n} #)
reallocWith ::
MonadIO m => String -> (Int -> Int) -> Int -> Array a -> m (Array a)
reallocWith :: forall (m :: * -> *) a.
MonadIO m =>
[Char] -> (Int -> Int) -> Int -> Array a -> m (Array a)
reallocWith [Char]
label Int -> Int
sizer Int
reqSize Array a
arr = do
let oldSize :: Int
oldSize = forall a. Array a -> Int
arrLen Array a
arr
newSize :: Int
newSize = Int -> Int
sizer Int
oldSize
safeSize :: Int
safeSize = forall a. Ord a => a -> a -> a
max Int
newSize (Int
oldSize forall a. Num a => a -> a -> a
+ Int
reqSize)
forall a. HasCallStack => Bool -> a -> a
assert (Int
newSize forall a. Ord a => a -> a -> Bool
>= Int
oldSize forall a. Num a => a -> a -> a
+ Int
reqSize Bool -> Bool -> Bool
|| forall a. HasCallStack => [Char] -> a
error [Char]
badSize) (forall (m :: * -> *) a. Monad m => a -> m a
return ())
forall (m :: * -> *) a. MonadIO m => Int -> Array a -> m (Array a)
realloc Int
safeSize Array a
arr
where
badSize :: [Char]
badSize = forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat
[ [Char]
label
, [Char]
": new array size is less than required size "
, forall a. Show a => a -> [Char]
show Int
reqSize
, [Char]
". Please check the sizing function passed."
]
{-# INLINE snocUnsafe #-}
snocUnsafe :: MonadIO m => Array a -> a -> m (Array a)
snocUnsafe :: forall (m :: * -> *) a. MonadIO m => Array a -> a -> m (Array a)
snocUnsafe arr :: Array a
arr@Array {Int
MutableArray# RealWorld a
arrTrueLen :: Int
arrLen :: Int
arrStart :: Int
arrContents# :: MutableArray# RealWorld a
arrTrueLen :: forall a. Array a -> Int
arrLen :: forall a. Array a -> Int
arrStart :: forall a. Array a -> Int
arrContents# :: forall a. Array a -> MutableArray# RealWorld a
..} a
a = do
forall a. HasCallStack => Bool -> a -> a
assert (Int
arrStart forall a. Num a => a -> a -> a
+ Int
arrLen forall a. Ord a => a -> a -> Bool
< Int
arrTrueLen) (forall (m :: * -> *) a. Monad m => a -> m a
return ())
forall (m :: * -> *) a. MonadIO m => Array a -> Int -> a -> m ()
putIndexUnsafe Array a
arr Int
arrLen a
a
forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Array a
arr {arrLen :: Int
arrLen = Int
arrLen forall a. Num a => a -> a -> a
+ Int
1}
{-# NOINLINE snocWithRealloc #-}
snocWithRealloc :: MonadIO m => (Int -> Int) -> Array a -> a -> m (Array a)
snocWithRealloc :: forall (m :: * -> *) a.
MonadIO m =>
(Int -> Int) -> Array a -> a -> m (Array a)
snocWithRealloc Int -> Int
sizer Array a
arr a
x = do
Array a
arr1 <- forall (m :: * -> *) a.
MonadIO m =>
[Char] -> (Int -> Int) -> Int -> Array a -> m (Array a)
reallocWith [Char]
"snocWithRealloc" Int -> Int
sizer Int
1 Array a
arr
forall (m :: * -> *) a. MonadIO m => Array a -> a -> m (Array a)
snocUnsafe Array a
arr1 a
x
{-# INLINE snocWith #-}
snocWith :: MonadIO m => (Int -> Int) -> Array a -> a -> m (Array a)
snocWith :: forall (m :: * -> *) a.
MonadIO m =>
(Int -> Int) -> Array a -> a -> m (Array a)
snocWith Int -> Int
sizer arr :: Array a
arr@Array {Int
MutableArray# RealWorld a
arrTrueLen :: Int
arrLen :: Int
arrStart :: Int
arrContents# :: MutableArray# RealWorld a
arrTrueLen :: forall a. Array a -> Int
arrLen :: forall a. Array a -> Int
arrStart :: forall a. Array a -> Int
arrContents# :: forall a. Array a -> MutableArray# RealWorld a
..} a
x = do
if Int
arrStart forall a. Num a => a -> a -> a
+ Int
arrLen forall a. Ord a => a -> a -> Bool
< Int
arrTrueLen
then forall (m :: * -> *) a. MonadIO m => Array a -> a -> m (Array a)
snocUnsafe Array a
arr a
x
else forall (m :: * -> *) a.
MonadIO m =>
(Int -> Int) -> Array a -> a -> m (Array a)
snocWithRealloc Int -> Int
sizer Array a
arr a
x
{-# INLINE snoc #-}
snoc :: MonadIO m => Array a -> a -> m (Array a)
snoc :: forall (m :: * -> *) a. MonadIO m => Array a -> a -> m (Array a)
snoc = forall (m :: * -> *) a.
MonadIO m =>
(Int -> Int) -> Array a -> a -> m (Array a)
snocWith (forall a. Num a => a -> a -> a
* Int
2)
{-# INLINE_NORMAL getIndexUnsafe #-}
getIndexUnsafe :: MonadIO m => Array a -> Int -> m a
getIndexUnsafe :: forall (m :: * -> *) a. MonadIO m => Array a -> Int -> m a
getIndexUnsafe Array {Int
MutableArray# RealWorld a
arrTrueLen :: Int
arrLen :: Int
arrStart :: Int
arrContents# :: MutableArray# RealWorld a
arrTrueLen :: forall a. Array a -> Int
arrLen :: forall a. Array a -> Int
arrStart :: forall a. Array a -> Int
arrContents# :: forall a. Array a -> MutableArray# RealWorld a
..} Int
n =
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO
forall a b. (a -> b) -> a -> b
$ forall a. (State# RealWorld -> (# State# RealWorld, a #)) -> IO a
IO
forall a b. (a -> b) -> a -> b
$ \State# RealWorld
s# ->
let !(I# Int#
i#) = Int
arrStart forall a. Num a => a -> a -> a
+ Int
n
in forall d a.
MutableArray# d a -> Int# -> State# d -> (# State# d, a #)
readArray# MutableArray# RealWorld a
arrContents# Int#
i# State# RealWorld
s#
{-# INLINE getIndex #-}
getIndex :: MonadIO m => Array a -> Int -> m a
getIndex :: forall (m :: * -> *) a. MonadIO m => Array a -> Int -> m a
getIndex arr :: Array a
arr@Array {Int
MutableArray# RealWorld a
arrTrueLen :: Int
arrLen :: Int
arrStart :: Int
arrContents# :: MutableArray# RealWorld a
arrTrueLen :: forall a. Array a -> Int
arrLen :: forall a. Array a -> Int
arrStart :: forall a. Array a -> Int
arrContents# :: forall a. Array a -> MutableArray# RealWorld a
..} Int
i =
if Int
i forall a. Ord a => a -> a -> Bool
>= Int
0 Bool -> Bool -> Bool
&& Int
i forall a. Ord a => a -> a -> Bool
< Int
arrLen
then forall (m :: * -> *) a. MonadIO m => Array a -> Int -> m a
getIndexUnsafe Array a
arr Int
i
else forall a. [Char] -> Int -> a
invalidIndex [Char]
"getIndex" Int
i
{-# INLINE getSliceUnsafe #-}
getSliceUnsafe
:: Int
-> Int
-> Array a
-> Array a
getSliceUnsafe :: forall a. Int -> Int -> Array a -> Array a
getSliceUnsafe Int
index Int
len arr :: Array a
arr@Array {Int
MutableArray# RealWorld a
arrTrueLen :: Int
arrLen :: Int
arrStart :: Int
arrContents# :: MutableArray# RealWorld a
arrTrueLen :: forall a. Array a -> Int
arrLen :: forall a. Array a -> Int
arrStart :: forall a. Array a -> Int
arrContents# :: forall a. Array a -> MutableArray# RealWorld a
..} =
forall a. HasCallStack => Bool -> a -> a
assert (Int
index forall a. Ord a => a -> a -> Bool
>= Int
0 Bool -> Bool -> Bool
&& Int
len forall a. Ord a => a -> a -> Bool
>= Int
0 Bool -> Bool -> Bool
&& Int
index forall a. Num a => a -> a -> a
+ Int
len forall a. Ord a => a -> a -> Bool
<= Int
arrLen)
forall a b. (a -> b) -> a -> b
$ Array a
arr {arrStart :: Int
arrStart = Int
arrStart forall a. Num a => a -> a -> a
+ Int
index, arrLen :: Int
arrLen = Int
len}
{-# INLINE getSlice #-}
getSlice
:: Int
-> Int
-> Array a
-> Array a
getSlice :: forall a. Int -> Int -> Array a -> Array a
getSlice Int
index Int
len arr :: Array a
arr@Array{Int
MutableArray# RealWorld a
arrTrueLen :: Int
arrLen :: Int
arrStart :: Int
arrContents# :: MutableArray# RealWorld a
arrTrueLen :: forall a. Array a -> Int
arrLen :: forall a. Array a -> Int
arrStart :: forall a. Array a -> Int
arrContents# :: forall a. Array a -> MutableArray# RealWorld a
..} =
if Int
index forall a. Ord a => a -> a -> Bool
>= Int
0 Bool -> Bool -> Bool
&& Int
len forall a. Ord a => a -> a -> Bool
>= Int
0 Bool -> Bool -> Bool
&& Int
index forall a. Num a => a -> a -> a
+ Int
len forall a. Ord a => a -> a -> Bool
<= Int
arrLen
then Array a
arr {arrStart :: Int
arrStart = Int
arrStart forall a. Num a => a -> a -> a
+ Int
index, arrLen :: Int
arrLen = Int
len}
else forall a. HasCallStack => [Char] -> a
error
forall a b. (a -> b) -> a -> b
$ [Char]
"getSlice: invalid slice, index "
forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> [Char]
show Int
index forall a. [a] -> [a] -> [a]
++ [Char]
" length " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> [Char]
show Int
len
{-# INLINE toList #-}
toList :: MonadIO m => Array a -> m [a]
toList :: forall (m :: * -> *) a. MonadIO m => Array a -> m [a]
toList arr :: Array a
arr@Array{Int
MutableArray# RealWorld a
arrTrueLen :: Int
arrLen :: Int
arrStart :: Int
arrContents# :: MutableArray# RealWorld a
arrTrueLen :: forall a. Array a -> Int
arrLen :: forall a. Array a -> Int
arrStart :: forall a. Array a -> Int
arrContents# :: forall a. Array a -> MutableArray# RealWorld a
..} = forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM (forall (m :: * -> *) a. MonadIO m => Array a -> Int -> m a
getIndexUnsafe Array a
arr) [Int
0 .. (Int
arrLen forall a. Num a => a -> a -> a
- Int
1)]
{-# INLINE_NORMAL toStreamD #-}
toStreamD :: MonadIO m => Array a -> D.Stream m a
toStreamD :: forall (m :: * -> *) a. MonadIO m => Array a -> Stream m a
toStreamD arr :: Array a
arr@Array{Int
MutableArray# RealWorld a
arrTrueLen :: Int
arrLen :: Int
arrStart :: Int
arrContents# :: MutableArray# RealWorld a
arrTrueLen :: forall a. Array a -> Int
arrLen :: forall a. Array a -> Int
arrStart :: forall a. Array a -> Int
arrContents# :: forall a. Array a -> MutableArray# RealWorld a
..} =
forall (m :: * -> *) a b.
Monad m =>
(a -> m b) -> Stream m a -> Stream m b
D.mapM (forall (m :: * -> *) a. MonadIO m => Array a -> Int -> m a
getIndexUnsafe Array a
arr) forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a.
(Monad m, Integral a) =>
a -> a -> Stream m a
D.enumerateFromToIntegral Int
0 (Int
arrLen forall a. Num a => a -> a -> a
- Int
1)
{-# INLINE toStreamK #-}
toStreamK :: MonadIO m => Array a -> K.Stream m a
toStreamK :: forall (m :: * -> *) a. MonadIO m => Array a -> Stream m a
toStreamK arr :: Array a
arr@Array{Int
MutableArray# RealWorld a
arrTrueLen :: Int
arrLen :: Int
arrStart :: Int
arrContents# :: MutableArray# RealWorld a
arrTrueLen :: forall a. Array a -> Int
arrLen :: forall a. Array a -> Int
arrStart :: forall a. Array a -> Int
arrContents# :: forall a. Array a -> MutableArray# RealWorld a
..} = forall (m :: * -> *) b a.
Monad m =>
(b -> m (Maybe (a, b))) -> b -> Stream m a
K.unfoldrM forall {m :: * -> *}. MonadIO m => Int -> m (Maybe (a, Int))
step Int
0
where
step :: Int -> m (Maybe (a, Int))
step Int
i
| Int
i forall a. Eq a => a -> a -> Bool
== Int
arrLen = forall (m :: * -> *) a. Monad m => a -> m a
return forall a. Maybe a
Nothing
| Bool
otherwise = do
a
x <- forall (m :: * -> *) a. MonadIO m => Array a -> Int -> m a
getIndexUnsafe Array a
arr Int
i
forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall a. a -> Maybe a
Just (a
x, Int
i forall a. Num a => a -> a -> a
+ Int
1)
{-# INLINE_NORMAL writeNUnsafe #-}
writeNUnsafe :: MonadIO m => Int -> Fold m a (Array a)
writeNUnsafe :: forall (m :: * -> *) a. MonadIO m => Int -> Fold m a (Array a)
writeNUnsafe Int
n = forall (m :: * -> *) a b s.
(s -> a -> m (Step s b))
-> m (Step s b) -> (s -> m b) -> Fold m a b
Fold forall {f :: * -> *} {a} {b}.
MonadIO f =>
Array a -> a -> f (Step (Array a) b)
step forall {a} {b}. m (Step (Array a) b)
initial forall (m :: * -> *) a. Monad m => a -> m a
return
where
initial :: m (Step (Array a) b)
initial = forall s b. s -> Step s b
FL.Partial forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (m :: * -> *) a. MonadIO m => Int -> m (Array a)
newArray (forall a. Ord a => a -> a -> a
max Int
n Int
0)
step :: Array a -> a -> f (Step (Array a) b)
step Array a
arr a
x = forall s b. s -> Step s b
FL.Partial forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (m :: * -> *) a. MonadIO m => Array a -> a -> m (Array a)
snocUnsafe Array a
arr a
x
{-# INLINE_NORMAL writeN #-}
writeN :: MonadIO m => Int -> Fold m a (Array a)
writeN :: forall (m :: * -> *) a. MonadIO m => Int -> Fold m a (Array a)
writeN Int
n = forall (m :: * -> *) a b.
Monad m =>
Int -> Fold m a b -> Fold m a b
FL.take Int
n forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. MonadIO m => Int -> Fold m a (Array a)
writeNUnsafe Int
n
{-# INLINE_NORMAL producer #-}
producer :: MonadIO m => Producer m (Array a) a
producer :: forall (m :: * -> *) a. MonadIO m => Producer m (Array a) a
producer = forall (m :: * -> *) a b s.
(s -> m (Step s b)) -> (a -> m s) -> (s -> m a) -> Producer m a b
Producer forall {m :: * -> *} {a}.
MonadIO m =>
(Array a, Int) -> m (Step (Array a, Int) a)
step forall {m :: * -> *} {b} {a}. (Monad m, Num b) => a -> m (a, b)
inject forall {m :: * -> *} {a}. Monad m => (Array a, Int) -> m (Array a)
extract
where
{-# INLINE inject #-}
inject :: a -> m (a, b)
inject a
arr = forall (m :: * -> *) a. Monad m => a -> m a
return (a
arr, b
0)
{-# INLINE extract #-}
extract :: (Array a, Int) -> m (Array a)
extract (Array a
arr, Int
i) =
forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Array a
arr {arrStart :: Int
arrStart = forall a. Array a -> Int
arrStart Array a
arr forall a. Num a => a -> a -> a
+ Int
i, arrLen :: Int
arrLen = forall a. Array a -> Int
arrLen Array a
arr forall a. Num a => a -> a -> a
- Int
i}
{-# INLINE_LATE step #-}
step :: (Array a, Int) -> m (Step (Array a, Int) a)
step (Array a
arr, Int
i)
| forall a. HasCallStack => Bool -> a -> a
assert (forall a. Array a -> Int
arrLen Array a
arr forall a. Ord a => a -> a -> Bool
>= Int
0) (Int
i forall a. Eq a => a -> a -> Bool
== forall a. Array a -> Int
arrLen Array a
arr) = forall (m :: * -> *) a. Monad m => a -> m a
return forall s a. Step s a
D.Stop
step (Array a
arr, Int
i) = do
a
x <- forall (m :: * -> *) a. MonadIO m => Array a -> Int -> m a
getIndexUnsafe Array a
arr Int
i
forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall s a. a -> s -> Step s a
D.Yield a
x (Array a
arr, Int
i forall a. Num a => a -> a -> a
+ Int
1)
{-# INLINE_NORMAL read #-}
read :: MonadIO m => Unfold m (Array a) a
read :: forall (m :: * -> *) a. MonadIO m => Unfold m (Array a) a
read = forall (m :: * -> *) a b. Producer m a b -> Unfold m a b
Producer.simplify forall (m :: * -> *) a. MonadIO m => Producer m (Array a) a
producer