{-# OPTIONS_GHC -fno-warn-orphans #-}

{-# LANGUAGE CPP           #-}
{-# LANGUAGE MagicHash     #-}
{-# LANGUAGE UnboxedTuples #-}

#include "inline.hs"

-- |
-- Module      : Streamly.Internal.Data.Prim.Array
-- Copyright   : (c) 2019 Composewell Technologies
--
-- License     : BSD-3-Clause
-- Maintainer  : streamly@composewell.com
-- Stability   : experimental
-- Portability : GHC
--
module Streamly.Internal.Data.Prim.Array
    (

    -- XXX should it be just Array instead? We should be able to replace one
    -- array type with another easily.
      PrimArray(..)

    -- XXX Prim should be exported from Data.Prim module?
    , Prim(..)

    , foldl'
    , foldr

    , length

    , writeN
    , write

    , toStreamD
    , toStreamDRev

    , toStream
    , toStreamRev
    , read
    , readSlice

    , fromListN
    , fromList
    , fromStreamDN
    , fromStreamD

    , fromStreamN
    , fromStream

    , streamFold
    , fold
    )
where

import Prelude hiding (foldr, length, read)
import Control.DeepSeq (NFData(..))
import Control.Monad (when)
import Control.Monad.IO.Class (liftIO, MonadIO)
import GHC.IO (unsafePerformIO)
import Data.Primitive.Types (Prim(..))

import Streamly.Internal.Data.Prim.Array.Types
import Streamly.Internal.Data.Unfold.Types (Unfold(..))
import Streamly.Internal.Data.Fold.Types (Fold(..))
import Streamly.Internal.Data.Stream.StreamK.Type (IsStream)
import Streamly.Internal.Data.Stream.Serial (SerialT)

import qualified Streamly.Internal.Data.Stream.StreamD as D

{-# INLINE_NORMAL toStreamD #-}
toStreamD :: (Prim a, Monad m) => PrimArray a -> D.Stream m a
toStreamD :: PrimArray a -> Stream m a
toStreamD PrimArray a
arr = (State Stream m a -> Int -> m (Step Int a)) -> Int -> Stream m a
forall (m :: * -> *) a s.
(State Stream m a -> s -> m (Step s a)) -> s -> Stream m a
D.Stream State Stream m a -> Int -> m (Step Int a)
forall (m :: * -> *) p. Monad m => p -> Int -> m (Step Int a)
step Int
0
  where
    {-# INLINE_LATE step #-}
    step :: p -> Int -> m (Step Int a)
step p
_ Int
i
        | Int
i Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== PrimArray a -> Int
forall a. Prim a => PrimArray a -> Int
sizeofPrimArray PrimArray a
arr = Step Int a -> m (Step Int a)
forall (m :: * -> *) a. Monad m => a -> m a
return Step Int a
forall s a. Step s a
D.Stop
    step p
_ Int
i = Step Int a -> m (Step Int a)
forall (m :: * -> *) a. Monad m => a -> m a
return (Step Int a -> m (Step Int a)) -> Step Int a -> m (Step Int a)
forall a b. (a -> b) -> a -> b
$ a -> Int -> Step Int a
forall s a. a -> s -> Step s a
D.Yield (PrimArray a -> Int -> a
forall a. Prim a => PrimArray a -> Int -> a
indexPrimArray PrimArray a
arr Int
i) (Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1)

{-# INLINE length #-}
length :: Prim a => PrimArray a -> Int
length :: PrimArray a -> Int
length PrimArray a
arr = PrimArray a -> Int
forall a. Prim a => PrimArray a -> Int
sizeofPrimArray PrimArray a
arr

{-# INLINE_NORMAL toStreamDRev #-}
toStreamDRev :: (Prim a, Monad m) => PrimArray a -> D.Stream m a
toStreamDRev :: PrimArray a -> Stream m a
toStreamDRev PrimArray a
arr = (State Stream m a -> Int -> m (Step Int a)) -> Int -> Stream m a
forall (m :: * -> *) a s.
(State Stream m a -> s -> m (Step s a)) -> s -> Stream m a
D.Stream State Stream m a -> Int -> m (Step Int a)
forall (m :: * -> *) p. Monad m => p -> Int -> m (Step Int a)
step (PrimArray a -> Int
forall a. Prim a => PrimArray a -> Int
sizeofPrimArray PrimArray a
arr Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1)
  where
    {-# INLINE_LATE step #-}
    step :: p -> Int -> m (Step Int a)
step p
_ Int
i
        | Int
i Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
0 = Step Int a -> m (Step Int a)
forall (m :: * -> *) a. Monad m => a -> m a
return Step Int a
forall s a. Step s a
D.Stop
    step p
_ Int
i = Step Int a -> m (Step Int a)
forall (m :: * -> *) a. Monad m => a -> m a
return (Step Int a -> m (Step Int a)) -> Step Int a -> m (Step Int a)
forall a b. (a -> b) -> a -> b
$ a -> Int -> Step Int a
forall s a. a -> s -> Step s a
D.Yield (PrimArray a -> Int -> a
forall a. Prim a => PrimArray a -> Int -> a
indexPrimArray PrimArray a
arr Int
i) (Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1)

{-# INLINE_NORMAL foldl' #-}
foldl' :: Prim a => (b -> a -> b) -> b -> PrimArray a -> b
foldl' :: (b -> a -> b) -> b -> PrimArray a -> b
foldl' = (b -> a -> b) -> b -> PrimArray a -> b
forall a b. Prim a => (b -> a -> b) -> b -> PrimArray a -> b
foldlPrimArray'

{-# INLINE_NORMAL foldr #-}
foldr :: Prim a => (a -> b -> b) -> b -> PrimArray a -> b
foldr :: (a -> b -> b) -> b -> PrimArray a -> b
foldr = (a -> b -> b) -> b -> PrimArray a -> b
forall a b. Prim a => (a -> b -> b) -> b -> PrimArray a -> b
foldrPrimArray

-- writeN n = S.evertM (fromStreamDN n)
{-# INLINE_NORMAL writeN #-}
writeN :: (MonadIO m, Prim a) => Int -> Fold m a (PrimArray a)
writeN :: Int -> Fold m a (PrimArray a)
writeN Int
limit = ((MutablePrimArray RealWorld a, Int)
 -> a -> m (MutablePrimArray RealWorld a, Int))
-> m (MutablePrimArray RealWorld a, Int)
-> ((MutablePrimArray RealWorld a, Int) -> m (PrimArray a))
-> Fold m a (PrimArray a)
forall (m :: * -> *) a b s.
(s -> a -> m s) -> m s -> (s -> m b) -> Fold m a b
Fold (MutablePrimArray RealWorld a, Int)
-> a -> m (MutablePrimArray RealWorld a, Int)
forall (m :: * -> *) a.
(MonadIO m, Prim a) =>
(MutablePrimArray RealWorld a, Int)
-> a -> m (MutablePrimArray RealWorld a, Int)
step m (MutablePrimArray RealWorld a, Int)
initial (MutablePrimArray RealWorld a, Int) -> m (PrimArray a)
forall (m :: * -> *) a b.
MonadIO m =>
(MutablePrimArray RealWorld a, b) -> m (PrimArray a)
extract
  where
    initial :: m (MutablePrimArray RealWorld a, Int)
initial = do
        MutablePrimArray RealWorld a
marr <- IO (MutablePrimArray RealWorld a)
-> m (MutablePrimArray RealWorld a)
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO (MutablePrimArray RealWorld a)
 -> m (MutablePrimArray RealWorld a))
-> IO (MutablePrimArray RealWorld a)
-> m (MutablePrimArray RealWorld a)
forall a b. (a -> b) -> a -> b
$ Int -> IO (MutablePrimArray (PrimState IO) a)
forall (m :: * -> *) a.
(PrimMonad m, Prim a) =>
Int -> m (MutablePrimArray (PrimState m) a)
newPrimArray Int
limit
        (MutablePrimArray RealWorld a, Int)
-> m (MutablePrimArray RealWorld a, Int)
forall (m :: * -> *) a. Monad m => a -> m a
return (MutablePrimArray RealWorld a
marr, Int
0)
    step :: (MutablePrimArray RealWorld a, Int)
-> a -> m (MutablePrimArray RealWorld a, Int)
step (MutablePrimArray RealWorld a
marr, Int
i) a
x
        | Int
i Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
limit = (MutablePrimArray RealWorld a, Int)
-> m (MutablePrimArray RealWorld a, Int)
forall (m :: * -> *) a. Monad m => a -> m a
return (MutablePrimArray RealWorld a
marr, Int
i)
        | Bool
otherwise = do
            IO () -> m ()
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> m ()) -> IO () -> m ()
forall a b. (a -> b) -> a -> b
$ MutablePrimArray (PrimState IO) a -> Int -> a -> IO ()
forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutablePrimArray (PrimState m) a -> Int -> a -> m ()
writePrimArray MutablePrimArray RealWorld a
MutablePrimArray (PrimState IO) a
marr Int
i a
x
            (MutablePrimArray RealWorld a, Int)
-> m (MutablePrimArray RealWorld a, Int)
forall (m :: * -> *) a. Monad m => a -> m a
return (MutablePrimArray RealWorld a
marr, Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1)
    extract :: (MutablePrimArray RealWorld a, b) -> m (PrimArray a)
extract (MutablePrimArray RealWorld a
marr, b
_) = IO (PrimArray a) -> m (PrimArray a)
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO (PrimArray a) -> m (PrimArray a))
-> IO (PrimArray a) -> m (PrimArray a)
forall a b. (a -> b) -> a -> b
$ MutablePrimArray (PrimState IO) a -> IO (PrimArray a)
forall (m :: * -> *) a.
PrimMonad m =>
MutablePrimArray (PrimState m) a -> m (PrimArray a)
unsafeFreezePrimArray MutablePrimArray RealWorld a
MutablePrimArray (PrimState IO) a
marr

{-# INLINE_NORMAL write #-}
write :: (MonadIO m, Prim a) => Fold m a (PrimArray a)
write :: Fold m a (PrimArray a)
write = ((MutablePrimArray RealWorld a, Int, Int)
 -> a -> m (MutablePrimArray RealWorld a, Int, Int))
-> m (MutablePrimArray RealWorld a, Int, Int)
-> ((MutablePrimArray RealWorld a, Int, Int) -> m (PrimArray a))
-> Fold m a (PrimArray a)
forall (m :: * -> *) a b s.
(s -> a -> m s) -> m s -> (s -> m b) -> Fold m a b
Fold (MutablePrimArray RealWorld a, Int, Int)
-> a -> m (MutablePrimArray RealWorld a, Int, Int)
forall (m :: * -> *) a.
(MonadIO m, Prim a) =>
(MutablePrimArray RealWorld a, Int, Int)
-> a -> m (MutablePrimArray RealWorld a, Int, Int)
step m (MutablePrimArray RealWorld a, Int, Int)
initial (MutablePrimArray RealWorld a, Int, Int) -> m (PrimArray a)
forall (m :: * -> *) a c.
(MonadIO m, Prim a) =>
(MutablePrimArray RealWorld a, Int, c) -> m (PrimArray a)
extract
  where
    initial :: m (MutablePrimArray RealWorld a, Int, Int)
initial = do
        MutablePrimArray RealWorld a
marr <- IO (MutablePrimArray RealWorld a)
-> m (MutablePrimArray RealWorld a)
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO (MutablePrimArray RealWorld a)
 -> m (MutablePrimArray RealWorld a))
-> IO (MutablePrimArray RealWorld a)
-> m (MutablePrimArray RealWorld a)
forall a b. (a -> b) -> a -> b
$ Int -> IO (MutablePrimArray (PrimState IO) a)
forall (m :: * -> *) a.
(PrimMonad m, Prim a) =>
Int -> m (MutablePrimArray (PrimState m) a)
newPrimArray Int
0
        (MutablePrimArray RealWorld a, Int, Int)
-> m (MutablePrimArray RealWorld a, Int, Int)
forall (m :: * -> *) a. Monad m => a -> m a
return (MutablePrimArray RealWorld a
marr, Int
0, Int
0)
    step :: (MutablePrimArray RealWorld a, Int, Int)
-> a -> m (MutablePrimArray RealWorld a, Int, Int)
step (MutablePrimArray RealWorld a
marr, Int
i, Int
capacity) a
x
        | Int
i Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
capacity =
            let newCapacity :: Int
newCapacity = Int -> Int -> Int
forall a. Ord a => a -> a -> a
max (Int
capacity Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
2) Int
1
             in do MutablePrimArray RealWorld a
newMarr <- IO (MutablePrimArray RealWorld a)
-> m (MutablePrimArray RealWorld a)
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO (MutablePrimArray RealWorld a)
 -> m (MutablePrimArray RealWorld a))
-> IO (MutablePrimArray RealWorld a)
-> m (MutablePrimArray RealWorld a)
forall a b. (a -> b) -> a -> b
$ MutablePrimArray (PrimState IO) a
-> Int -> IO (MutablePrimArray (PrimState IO) a)
forall (m :: * -> *) a.
(PrimMonad m, Prim a) =>
MutablePrimArray (PrimState m) a
-> Int -> m (MutablePrimArray (PrimState m) a)
resizeMutablePrimArray MutablePrimArray RealWorld a
MutablePrimArray (PrimState IO) a
marr Int
newCapacity
                   IO () -> m ()
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> m ()) -> IO () -> m ()
forall a b. (a -> b) -> a -> b
$ MutablePrimArray (PrimState IO) a -> Int -> a -> IO ()
forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutablePrimArray (PrimState m) a -> Int -> a -> m ()
writePrimArray MutablePrimArray RealWorld a
MutablePrimArray (PrimState IO) a
newMarr Int
i a
x
                   (MutablePrimArray RealWorld a, Int, Int)
-> m (MutablePrimArray RealWorld a, Int, Int)
forall (m :: * -> *) a. Monad m => a -> m a
return (MutablePrimArray RealWorld a
newMarr, Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1, Int
newCapacity)
        | Bool
otherwise = do
            IO () -> m ()
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> m ()) -> IO () -> m ()
forall a b. (a -> b) -> a -> b
$ MutablePrimArray (PrimState IO) a -> Int -> a -> IO ()
forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutablePrimArray (PrimState m) a -> Int -> a -> m ()
writePrimArray MutablePrimArray RealWorld a
MutablePrimArray (PrimState IO) a
marr Int
i a
x
            (MutablePrimArray RealWorld a, Int, Int)
-> m (MutablePrimArray RealWorld a, Int, Int)
forall (m :: * -> *) a. Monad m => a -> m a
return (MutablePrimArray RealWorld a
marr, Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1, Int
capacity)
    extract :: (MutablePrimArray RealWorld a, Int, c) -> m (PrimArray a)
extract (MutablePrimArray RealWorld a
marr, Int
len, c
_) = do IO () -> m ()
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> m ()) -> IO () -> m ()
forall a b. (a -> b) -> a -> b
$ MutablePrimArray (PrimState IO) a -> Int -> IO ()
forall (m :: * -> *) a.
(PrimMonad m, Prim a) =>
MutablePrimArray (PrimState m) a -> Int -> m ()
shrinkMutablePrimArray MutablePrimArray RealWorld a
MutablePrimArray (PrimState IO) a
marr Int
len
                                IO (PrimArray a) -> m (PrimArray a)
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO (PrimArray a) -> m (PrimArray a))
-> IO (PrimArray a) -> m (PrimArray a)
forall a b. (a -> b) -> a -> b
$ MutablePrimArray (PrimState IO) a -> IO (PrimArray a)
forall (m :: * -> *) a.
PrimMonad m =>
MutablePrimArray (PrimState m) a -> m (PrimArray a)
unsafeFreezePrimArray MutablePrimArray RealWorld a
MutablePrimArray (PrimState IO) a
marr

{-# INLINE_NORMAL fromStreamDN #-}
fromStreamDN :: (MonadIO m, Prim a) => Int -> D.Stream m a -> m (PrimArray a)
fromStreamDN :: Int -> Stream m a -> m (PrimArray a)
fromStreamDN Int
limit Stream m a
str = do
    MutablePrimArray RealWorld a
marr <- IO (MutablePrimArray RealWorld a)
-> m (MutablePrimArray RealWorld a)
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO (MutablePrimArray RealWorld a)
 -> m (MutablePrimArray RealWorld a))
-> IO (MutablePrimArray RealWorld a)
-> m (MutablePrimArray RealWorld a)
forall a b. (a -> b) -> a -> b
$ Int -> IO (MutablePrimArray (PrimState IO) a)
forall (m :: * -> *) a.
(PrimMonad m, Prim a) =>
Int -> m (MutablePrimArray (PrimState m) a)
newPrimArray (Int -> Int -> Int
forall a. Ord a => a -> a -> a
max Int
limit Int
0)
    Int
_ <-
        (Int -> a -> m Int) -> Int -> Stream m a -> m Int
forall (m :: * -> *) b a.
Monad m =>
(b -> a -> m b) -> b -> Stream m a -> m b
D.foldlM'
            (\Int
i a
x -> Int
i Int -> m Int -> m Int
`seq` (IO () -> m ()
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> m ()) -> IO () -> m ()
forall a b. (a -> b) -> a -> b
$ MutablePrimArray (PrimState IO) a -> Int -> a -> IO ()
forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutablePrimArray (PrimState m) a -> Int -> a -> m ()
writePrimArray MutablePrimArray RealWorld a
MutablePrimArray (PrimState IO) a
marr Int
i a
x) m () -> m Int -> m Int
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Int -> m Int
forall (m :: * -> *) a. Monad m => a -> m a
return (Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1))
            Int
0 (Stream m a -> m Int) -> Stream m a -> m Int
forall a b. (a -> b) -> a -> b
$
        Int -> Stream m a -> Stream m a
forall (m :: * -> *) a. Monad m => Int -> Stream m a -> Stream m a
D.take Int
limit Stream m a
str
    IO (PrimArray a) -> m (PrimArray a)
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO (PrimArray a) -> m (PrimArray a))
-> IO (PrimArray a) -> m (PrimArray a)
forall a b. (a -> b) -> a -> b
$ MutablePrimArray (PrimState IO) a -> IO (PrimArray a)
forall (m :: * -> *) a.
PrimMonad m =>
MutablePrimArray (PrimState m) a -> m (PrimArray a)
unsafeFreezePrimArray MutablePrimArray RealWorld a
MutablePrimArray (PrimState IO) a
marr

{-# INLINE fromStreamD #-}
fromStreamD :: (MonadIO m, Prim a) => D.Stream m a -> m (PrimArray a)
fromStreamD :: Stream m a -> m (PrimArray a)
fromStreamD Stream m a
str = Fold m a (PrimArray a) -> Stream m a -> m (PrimArray a)
forall (m :: * -> *) a b.
Monad m =>
Fold m a b -> Stream m a -> m b
D.runFold Fold m a (PrimArray a)
forall (m :: * -> *) a.
(MonadIO m, Prim a) =>
Fold m a (PrimArray a)
write Stream m a
str

{-# INLINABLE fromListN #-}
fromListN :: Prim a => Int -> [a] -> PrimArray a
fromListN :: Int -> [a] -> PrimArray a
fromListN Int
n [a]
xs = IO (PrimArray a) -> PrimArray a
forall a. IO a -> a
unsafePerformIO (IO (PrimArray a) -> PrimArray a)
-> IO (PrimArray a) -> PrimArray a
forall a b. (a -> b) -> a -> b
$ Int -> Stream IO a -> IO (PrimArray a)
forall (m :: * -> *) a.
(MonadIO m, Prim a) =>
Int -> Stream m a -> m (PrimArray a)
fromStreamDN Int
n (Stream IO a -> IO (PrimArray a))
-> Stream IO a -> IO (PrimArray a)
forall a b. (a -> b) -> a -> b
$ [a] -> Stream IO a
forall (m :: * -> *) a. Applicative m => [a] -> Stream m a
D.fromList [a]
xs

{-# INLINABLE fromList #-}
fromList :: Prim a => [a] -> PrimArray a
fromList :: [a] -> PrimArray a
fromList [a]
xs = IO (PrimArray a) -> PrimArray a
forall a. IO a -> a
unsafePerformIO (IO (PrimArray a) -> PrimArray a)
-> IO (PrimArray a) -> PrimArray a
forall a b. (a -> b) -> a -> b
$ Stream IO a -> IO (PrimArray a)
forall (m :: * -> *) a.
(MonadIO m, Prim a) =>
Stream m a -> m (PrimArray a)
fromStreamD (Stream IO a -> IO (PrimArray a))
-> Stream IO a -> IO (PrimArray a)
forall a b. (a -> b) -> a -> b
$ [a] -> Stream IO a
forall (m :: * -> *) a. Applicative m => [a] -> Stream m a
D.fromList [a]
xs

instance Prim a => NFData (PrimArray a) where
    {-# INLINE rnf #-}
    rnf :: PrimArray a -> ()
rnf = (() -> a -> ()) -> () -> PrimArray a -> ()
forall a b. Prim a => (b -> a -> b) -> b -> PrimArray a -> b
foldl' (\()
_ a
_ -> ()) ()

{-# INLINE fromStreamN #-}
fromStreamN :: (MonadIO m, Prim a) => Int -> SerialT m a -> m (PrimArray a)
fromStreamN :: Int -> SerialT m a -> m (PrimArray a)
fromStreamN Int
n SerialT m a
m = do
    Bool -> m () -> m ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
0) (m () -> m ()) -> m () -> m ()
forall a b. (a -> b) -> a -> b
$ [Char] -> m ()
forall a. HasCallStack => [Char] -> a
error [Char]
"fromStreamN: negative write count specified"
    Int -> Stream m a -> m (PrimArray a)
forall (m :: * -> *) a.
(MonadIO m, Prim a) =>
Int -> Stream m a -> m (PrimArray a)
fromStreamDN Int
n (Stream m a -> m (PrimArray a)) -> Stream m a -> m (PrimArray a)
forall a b. (a -> b) -> a -> b
$ SerialT m a -> Stream m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(IsStream t, Monad m) =>
t m a -> Stream m a
D.toStreamD SerialT m a
m

{-# INLINE fromStream #-}
fromStream :: (MonadIO m, Prim a) => SerialT m a -> m (PrimArray a)
fromStream :: SerialT m a -> m (PrimArray a)
fromStream SerialT m a
m = Stream m a -> m (PrimArray a)
forall (m :: * -> *) a.
(MonadIO m, Prim a) =>
Stream m a -> m (PrimArray a)
fromStreamD (Stream m a -> m (PrimArray a)) -> Stream m a -> m (PrimArray a)
forall a b. (a -> b) -> a -> b
$ SerialT m a -> Stream m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(IsStream t, Monad m) =>
t m a -> Stream m a
D.toStreamD SerialT m a
m

{-# INLINE_EARLY toStream #-}
toStream :: (Prim a, Monad m, IsStream t) => PrimArray a -> t m a
toStream :: PrimArray a -> t m a
toStream = Stream m a -> t m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(IsStream t, Monad m) =>
Stream m a -> t m a
D.fromStreamD (Stream m a -> t m a)
-> (PrimArray a -> Stream m a) -> PrimArray a -> t m a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PrimArray a -> Stream m a
forall a (m :: * -> *).
(Prim a, Monad m) =>
PrimArray a -> Stream m a
toStreamD

{-# INLINE_EARLY toStreamRev #-}
toStreamRev :: (Prim a, Monad m, IsStream t) => PrimArray a -> t m a
toStreamRev :: PrimArray a -> t m a
toStreamRev = Stream m a -> t m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(IsStream t, Monad m) =>
Stream m a -> t m a
D.fromStreamD (Stream m a -> t m a)
-> (PrimArray a -> Stream m a) -> PrimArray a -> t m a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PrimArray a -> Stream m a
forall a (m :: * -> *).
(Prim a, Monad m) =>
PrimArray a -> Stream m a
toStreamDRev

{-# INLINE fold #-}
fold :: (Prim a, Monad m) => Fold m a b -> PrimArray a -> m b
fold :: Fold m a b -> PrimArray a -> m b
fold Fold m a b
f PrimArray a
arr = Fold m a b -> Stream m a -> m b
forall (m :: * -> *) a b.
Monad m =>
Fold m a b -> Stream m a -> m b
D.runFold Fold m a b
f (PrimArray a -> Stream m a
forall a (m :: * -> *).
(Prim a, Monad m) =>
PrimArray a -> Stream m a
toStreamD PrimArray a
arr)

{-# INLINE streamFold #-}
streamFold :: (Prim a, Monad m) => (SerialT m a -> m b) -> PrimArray a -> m b
streamFold :: (SerialT m a -> m b) -> PrimArray a -> m b
streamFold SerialT m a -> m b
f PrimArray a
arr = SerialT m a -> m b
f (PrimArray a -> SerialT m a
forall a (m :: * -> *) (t :: (* -> *) -> * -> *).
(Prim a, Monad m, IsStream t) =>
PrimArray a -> t m a
toStream PrimArray a
arr)

{-# INLINE_NORMAL read #-}
read :: (Prim a, Monad m) => Unfold m (PrimArray a) a
read :: Unfold m (PrimArray a) a
read = ((PrimArray a, Int) -> m (Step (PrimArray a, Int) a))
-> (PrimArray a -> m (PrimArray a, Int))
-> Unfold m (PrimArray a) a
forall (m :: * -> *) a b s.
(s -> m (Step s b)) -> (a -> m s) -> Unfold m a b
Unfold (PrimArray a, Int) -> m (Step (PrimArray a, Int) a)
forall a (m :: * -> *).
(Prim a, Monad m) =>
(PrimArray a, Int) -> m (Step (PrimArray a, Int) a)
step PrimArray a -> m (PrimArray a, Int)
forall (m :: * -> *) b a. (Monad m, Num b) => a -> m (a, b)
inject
  where
    inject :: a -> m (a, b)
inject a
arr = (a, b) -> m (a, b)
forall (m :: * -> *) a. Monad m => a -> m a
return (a
arr, b
0)
    step :: (PrimArray a, Int) -> m (Step (PrimArray a, Int) a)
step (PrimArray a
arr, Int
i)
        | Int
i Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== PrimArray a -> Int
forall a. Prim a => PrimArray a -> Int
length PrimArray a
arr = Step (PrimArray a, Int) a -> m (Step (PrimArray a, Int) a)
forall (m :: * -> *) a. Monad m => a -> m a
return Step (PrimArray a, Int) a
forall s a. Step s a
D.Stop
    step (PrimArray a
arr, Int
i) = Step (PrimArray a, Int) a -> m (Step (PrimArray a, Int) a)
forall (m :: * -> *) a. Monad m => a -> m a
return (Step (PrimArray a, Int) a -> m (Step (PrimArray a, Int) a))
-> Step (PrimArray a, Int) a -> m (Step (PrimArray a, Int) a)
forall a b. (a -> b) -> a -> b
$ a -> (PrimArray a, Int) -> Step (PrimArray a, Int) a
forall s a. a -> s -> Step s a
D.Yield (PrimArray a -> Int -> a
forall a. Prim a => PrimArray a -> Int -> a
indexPrimArray PrimArray a
arr Int
i) (PrimArray a
arr, Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1)

{-# INLINE_NORMAL readSlice #-}
readSlice :: (Prim a, Monad m) => Int -> Int -> Unfold m (PrimArray a) a
readSlice :: Int -> Int -> Unfold m (PrimArray a) a
readSlice Int
off Int
len = ((PrimArray a, Int) -> m (Step (PrimArray a, Int) a))
-> (PrimArray a -> m (PrimArray a, Int))
-> Unfold m (PrimArray a) a
forall (m :: * -> *) a b s.
(s -> m (Step s b)) -> (a -> m s) -> Unfold m a b
Unfold (PrimArray a, Int) -> m (Step (PrimArray a, Int) a)
forall a (m :: * -> *).
(Prim a, Monad m) =>
(PrimArray a, Int) -> m (Step (PrimArray a, Int) a)
step PrimArray a -> m (PrimArray a, Int)
forall (m :: * -> *) a. Monad m => a -> m (a, Int)
inject
  where
    inject :: a -> m (a, Int)
inject a
arr = (a, Int) -> m (a, Int)
forall (m :: * -> *) a. Monad m => a -> m a
return (a
arr, Int
off)
    step :: (PrimArray a, Int) -> m (Step (PrimArray a, Int) a)
step (PrimArray a
arr, Int
i)
        | Int
i Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int -> Int -> Int
forall a. Ord a => a -> a -> a
min (Int
off Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
len) (PrimArray a -> Int
forall a. Prim a => PrimArray a -> Int
length PrimArray a
arr) = Step (PrimArray a, Int) a -> m (Step (PrimArray a, Int) a)
forall (m :: * -> *) a. Monad m => a -> m a
return Step (PrimArray a, Int) a
forall s a. Step s a
D.Stop
    step (PrimArray a
arr, Int
i) = Step (PrimArray a, Int) a -> m (Step (PrimArray a, Int) a)
forall (m :: * -> *) a. Monad m => a -> m a
return (Step (PrimArray a, Int) a -> m (Step (PrimArray a, Int) a))
-> Step (PrimArray a, Int) a -> m (Step (PrimArray a, Int) a)
forall a b. (a -> b) -> a -> b
$ a -> (PrimArray a, Int) -> Step (PrimArray a, Int) a
forall s a. a -> s -> Step s a
D.Yield (PrimArray a -> Int -> a
forall a. Prim a => PrimArray a -> Int -> a
indexPrimArray PrimArray a
arr Int
i) (PrimArray a
arr, Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1)