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

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

#include "inline.hs"

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

    , foldl'
    , foldr

    , length

    , writeN
    , write

    , toStreamD
    , toStreamDRev

    , toStream
    , toStreamRev
    , read

    , fromListN
    , fromList
    , fromStreamDN
    , fromStreamD

    , fromStreamN
    , fromStream

    , streamFold
    , fold
    )
where

import Prelude hiding (foldr, length, read)
#if !MIN_VERSION_primitive(0,7,1)
import Control.DeepSeq (NFData(..))
#endif
import Control.Monad (when)
import Control.Monad.IO.Class (liftIO, MonadIO)
import GHC.IO (unsafePerformIO)
import GHC.Base (Int(..))
import Data.Functor.Identity (runIdentity)
import Data.Primitive.Array hiding (fromList, fromListN)
import qualified GHC.Exts as Exts

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

{-# NOINLINE bottomElement #-}
bottomElement :: a
bottomElement :: a
bottomElement = a
forall a. HasCallStack => a
undefined

{-# INLINE_NORMAL toStreamD #-}
toStreamD :: Monad m => Array a -> D.Stream m a
toStreamD :: Array a -> Stream m a
toStreamD Array 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
== Array a -> Int
forall a. Array a -> Int
length Array 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
_ (I# 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
$
        case Array# a -> Int# -> (# a #)
forall a. Array# a -> Int# -> (# a #)
Exts.indexArray# (Array a -> Array# a
forall a. Array a -> Array# a
array# Array a
arr) Int#
i of
            (# a
x #) -> a -> Int -> Step Int a
forall s a. a -> s -> Step s a
D.Yield a
x ((Int# -> Int
I# Int#
i) Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1)

{-# INLINE length #-}
length :: Array a -> Int
length :: Array a -> Int
length Array a
arr = Array a -> Int
forall a. Array a -> Int
sizeofArray Array a
arr

{-# INLINE_NORMAL toStreamDRev #-}
toStreamDRev :: Monad m => Array a -> D.Stream m a
toStreamDRev :: Array a -> Stream m a
toStreamDRev Array 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 (Array a -> Int
forall a. Array a -> Int
length Array 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
_ (I# 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
$
        case Array# a -> Int# -> (# a #)
forall a. Array# a -> Int# -> (# a #)
Exts.indexArray# (Array a -> Array# a
forall a. Array a -> Array# a
array# Array a
arr) Int#
i of
            (# a
x #) -> a -> Int -> Step Int a
forall s a. a -> s -> Step s a
D.Yield a
x ((Int# -> Int
I# Int#
i) Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1)

{-# INLINE_NORMAL foldl' #-}
foldl' :: (b -> a -> b) -> b -> Array a -> b
foldl' :: (b -> a -> b) -> b -> Array a -> b
foldl' b -> a -> b
f b
z Array a
arr = Identity b -> b
forall a. Identity a -> a
runIdentity (Identity b -> b) -> Identity b -> b
forall a b. (a -> b) -> a -> b
$ (b -> a -> b) -> b -> Stream Identity a -> Identity b
forall (m :: * -> *) b a.
Monad m =>
(b -> a -> b) -> b -> Stream m a -> m b
D.foldl' b -> a -> b
f b
z (Stream Identity a -> Identity b)
-> Stream Identity a -> Identity b
forall a b. (a -> b) -> a -> b
$ Array a -> Stream Identity a
forall (m :: * -> *) a. Monad m => Array a -> Stream m a
toStreamD Array a
arr

{-# INLINE_NORMAL foldr #-}
foldr :: (a -> b -> b) -> b -> Array a -> b
foldr :: (a -> b -> b) -> b -> Array a -> b
foldr a -> b -> b
f b
z Array a
arr = Identity b -> b
forall a. Identity a -> a
runIdentity (Identity b -> b) -> Identity b -> b
forall a b. (a -> b) -> a -> b
$ (a -> b -> b) -> b -> Stream Identity a -> Identity b
forall (m :: * -> *) a b.
Monad m =>
(a -> b -> b) -> b -> Stream m a -> m b
D.foldr a -> b -> b
f b
z (Stream Identity a -> Identity b)
-> Stream Identity a -> Identity b
forall a b. (a -> b) -> a -> b
$ Array a -> Stream Identity a
forall (m :: * -> *) a. Monad m => Array a -> Stream m a
toStreamD Array a
arr

-- writeN n = S.evertM (fromStreamDN n)
{-# INLINE_NORMAL writeN #-}
writeN :: MonadIO m => Int -> Fold m a (Array a)
writeN :: Int -> Fold m a (Array a)
writeN Int
limit = ((MutableArray RealWorld a, Int)
 -> a -> m (MutableArray RealWorld a, Int))
-> m (MutableArray RealWorld a, Int)
-> ((MutableArray RealWorld a, Int) -> m (Array a))
-> Fold m a (Array a)
forall (m :: * -> *) a b s.
(s -> a -> m s) -> m s -> (s -> m b) -> Fold m a b
Fold (MutableArray RealWorld a, Int)
-> a -> m (MutableArray RealWorld a, Int)
forall (m :: * -> *) a.
MonadIO m =>
(MutableArray RealWorld a, Int)
-> a -> m (MutableArray RealWorld a, Int)
step m (MutableArray RealWorld a, Int)
forall a. m (MutableArray RealWorld a, Int)
initial (MutableArray RealWorld a, Int) -> m (Array a)
forall (m :: * -> *) a.
MonadIO m =>
(MutableArray RealWorld a, Int) -> m (Array a)
extract
  where
    initial :: m (MutableArray RealWorld a, Int)
initial = do
        MutableArray RealWorld a
marr <- IO (MutableArray RealWorld a) -> m (MutableArray RealWorld a)
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO (MutableArray RealWorld a) -> m (MutableArray RealWorld a))
-> IO (MutableArray RealWorld a) -> m (MutableArray RealWorld a)
forall a b. (a -> b) -> a -> b
$ Int -> a -> IO (MutableArray (PrimState IO) a)
forall (m :: * -> *) a.
PrimMonad m =>
Int -> a -> m (MutableArray (PrimState m) a)
newArray Int
limit a
forall a. a
bottomElement
        (MutableArray RealWorld a, Int)
-> m (MutableArray RealWorld a, Int)
forall (m :: * -> *) a. Monad m => a -> m a
return (MutableArray RealWorld a
marr, Int
0)
    step :: (MutableArray RealWorld a, Int)
-> a -> m (MutableArray RealWorld a, Int)
step (MutableArray RealWorld a
marr, Int
i) a
x
        | Int
i Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
limit = (MutableArray RealWorld a, Int)
-> m (MutableArray RealWorld a, Int)
forall (m :: * -> *) a. Monad m => a -> m a
return (MutableArray 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
$ MutableArray (PrimState IO) a -> Int -> a -> IO ()
forall (m :: * -> *) a.
PrimMonad m =>
MutableArray (PrimState m) a -> Int -> a -> m ()
writeArray MutableArray RealWorld a
MutableArray (PrimState IO) a
marr Int
i a
x
            (MutableArray RealWorld a, Int)
-> m (MutableArray RealWorld a, Int)
forall (m :: * -> *) a. Monad m => a -> m a
return (MutableArray RealWorld a
marr, Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1)
    extract :: (MutableArray RealWorld a, Int) -> m (Array a)
extract (MutableArray RealWorld a
marr, Int
len) = IO (Array a) -> m (Array a)
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO (Array a) -> m (Array a)) -> IO (Array a) -> m (Array a)
forall a b. (a -> b) -> a -> b
$ MutableArray (PrimState IO) a -> Int -> Int -> IO (Array a)
forall (m :: * -> *) a.
PrimMonad m =>
MutableArray (PrimState m) a -> Int -> Int -> m (Array a)
freezeArray MutableArray RealWorld a
MutableArray (PrimState IO) a
marr Int
0 Int
len

{-# INLINE_NORMAL write #-}
write :: MonadIO m => Fold m a (Array a)
write :: Fold m a (Array a)
write = ((MutableArray RealWorld a, Int, Int)
 -> a -> m (MutableArray RealWorld a, Int, Int))
-> m (MutableArray RealWorld a, Int, Int)
-> ((MutableArray RealWorld a, Int, Int) -> m (Array a))
-> Fold m a (Array a)
forall (m :: * -> *) a b s.
(s -> a -> m s) -> m s -> (s -> m b) -> Fold m a b
Fold (MutableArray RealWorld a, Int, Int)
-> a -> m (MutableArray RealWorld a, Int, Int)
forall (m :: * -> *) a.
MonadIO m =>
(MutableArray RealWorld a, Int, Int)
-> a -> m (MutableArray RealWorld a, Int, Int)
step m (MutableArray RealWorld a, Int, Int)
forall a. m (MutableArray RealWorld a, Int, Int)
initial (MutableArray RealWorld a, Int, Int) -> m (Array a)
forall (m :: * -> *) a c.
MonadIO m =>
(MutableArray RealWorld a, Int, c) -> m (Array a)
extract
  where
    initial :: m (MutableArray RealWorld a, Int, Int)
initial = do
        MutableArray RealWorld a
marr <- IO (MutableArray RealWorld a) -> m (MutableArray RealWorld a)
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO (MutableArray RealWorld a) -> m (MutableArray RealWorld a))
-> IO (MutableArray RealWorld a) -> m (MutableArray RealWorld a)
forall a b. (a -> b) -> a -> b
$ Int -> a -> IO (MutableArray (PrimState IO) a)
forall (m :: * -> *) a.
PrimMonad m =>
Int -> a -> m (MutableArray (PrimState m) a)
newArray Int
0 a
forall a. a
bottomElement
        (MutableArray RealWorld a, Int, Int)
-> m (MutableArray RealWorld a, Int, Int)
forall (m :: * -> *) a. Monad m => a -> m a
return (MutableArray RealWorld a
marr, Int
0, Int
0)
    step :: (MutableArray RealWorld a, Int, Int)
-> a -> m (MutableArray RealWorld a, Int, Int)
step (MutableArray 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 MutableArray RealWorld a
newMarr <- IO (MutableArray RealWorld a) -> m (MutableArray RealWorld a)
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO (MutableArray RealWorld a) -> m (MutableArray RealWorld a))
-> IO (MutableArray RealWorld a) -> m (MutableArray RealWorld a)
forall a b. (a -> b) -> a -> b
$ Int -> a -> IO (MutableArray (PrimState IO) a)
forall (m :: * -> *) a.
PrimMonad m =>
Int -> a -> m (MutableArray (PrimState m) a)
newArray Int
newCapacity a
forall a. a
bottomElement
                   IO () -> m ()
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> m ()) -> IO () -> m ()
forall a b. (a -> b) -> a -> b
$ MutableArray (PrimState IO) a
-> Int -> MutableArray (PrimState IO) a -> Int -> Int -> IO ()
forall (m :: * -> *) a.
PrimMonad m =>
MutableArray (PrimState m) a
-> Int -> MutableArray (PrimState m) a -> Int -> Int -> m ()
copyMutableArray MutableArray RealWorld a
MutableArray (PrimState IO) a
newMarr Int
0 MutableArray RealWorld a
MutableArray (PrimState IO) a
marr Int
0 Int
i
                   IO () -> m ()
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> m ()) -> IO () -> m ()
forall a b. (a -> b) -> a -> b
$ MutableArray (PrimState IO) a -> Int -> a -> IO ()
forall (m :: * -> *) a.
PrimMonad m =>
MutableArray (PrimState m) a -> Int -> a -> m ()
writeArray MutableArray RealWorld a
MutableArray (PrimState IO) a
newMarr Int
i a
x
                   (MutableArray RealWorld a, Int, Int)
-> m (MutableArray RealWorld a, Int, Int)
forall (m :: * -> *) a. Monad m => a -> m a
return (MutableArray 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
$ MutableArray (PrimState IO) a -> Int -> a -> IO ()
forall (m :: * -> *) a.
PrimMonad m =>
MutableArray (PrimState m) a -> Int -> a -> m ()
writeArray MutableArray RealWorld a
MutableArray (PrimState IO) a
marr Int
i a
x
            (MutableArray RealWorld a, Int, Int)
-> m (MutableArray RealWorld a, Int, Int)
forall (m :: * -> *) a. Monad m => a -> m a
return (MutableArray RealWorld a
marr, Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1, Int
capacity)
    extract :: (MutableArray RealWorld a, Int, c) -> m (Array a)
extract (MutableArray RealWorld a
marr, Int
len, c
_) = IO (Array a) -> m (Array a)
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO (Array a) -> m (Array a)) -> IO (Array a) -> m (Array a)
forall a b. (a -> b) -> a -> b
$ MutableArray (PrimState IO) a -> Int -> Int -> IO (Array a)
forall (m :: * -> *) a.
PrimMonad m =>
MutableArray (PrimState m) a -> Int -> Int -> m (Array a)
freezeArray MutableArray RealWorld a
MutableArray (PrimState IO) a
marr Int
0 Int
len

{-# INLINE_NORMAL fromStreamDN #-}
fromStreamDN :: MonadIO m => Int -> D.Stream m a -> m (Array a)
fromStreamDN :: Int -> Stream m a -> m (Array a)
fromStreamDN Int
limit Stream m a
str = do
    MutableArray RealWorld a
marr <- IO (MutableArray RealWorld a) -> m (MutableArray RealWorld a)
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO (MutableArray RealWorld a) -> m (MutableArray RealWorld a))
-> IO (MutableArray RealWorld a) -> m (MutableArray RealWorld a)
forall a b. (a -> b) -> a -> b
$ Int -> a -> IO (MutableArray (PrimState IO) a)
forall (m :: * -> *) a.
PrimMonad m =>
Int -> a -> m (MutableArray (PrimState m) a)
newArray (Int -> Int -> Int
forall a. Ord a => a -> a -> a
max Int
limit Int
0) a
forall a. a
bottomElement
    Int
i <-
        (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
$ MutableArray (PrimState IO) a -> Int -> a -> IO ()
forall (m :: * -> *) a.
PrimMonad m =>
MutableArray (PrimState m) a -> Int -> a -> m ()
writeArray MutableArray RealWorld a
MutableArray (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 (Array a) -> m (Array a)
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO (Array a) -> m (Array a)) -> IO (Array a) -> m (Array a)
forall a b. (a -> b) -> a -> b
$ MutableArray (PrimState IO) a -> Int -> Int -> IO (Array a)
forall (m :: * -> *) a.
PrimMonad m =>
MutableArray (PrimState m) a -> Int -> Int -> m (Array a)
freezeArray MutableArray RealWorld a
MutableArray (PrimState IO) a
marr Int
0 Int
i

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

{-# INLINABLE fromListN #-}
fromListN :: Int -> [a] -> Array a
fromListN :: Int -> [a] -> Array a
fromListN Int
n [a]
xs = IO (Array a) -> Array a
forall a. IO a -> a
unsafePerformIO (IO (Array a) -> Array a) -> IO (Array a) -> Array a
forall a b. (a -> b) -> a -> b
$ Int -> Stream IO a -> IO (Array a)
forall (m :: * -> *) a.
MonadIO m =>
Int -> Stream m a -> m (Array a)
fromStreamDN Int
n (Stream IO a -> IO (Array a)) -> Stream IO a -> IO (Array 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 :: [a] -> Array a
fromList :: [a] -> Array a
fromList [a]
xs = IO (Array a) -> Array a
forall a. IO a -> a
unsafePerformIO (IO (Array a) -> Array a) -> IO (Array a) -> Array a
forall a b. (a -> b) -> a -> b
$ Stream IO a -> IO (Array a)
forall (m :: * -> *) a. MonadIO m => Stream m a -> m (Array a)
fromStreamD (Stream IO a -> IO (Array a)) -> Stream IO a -> IO (Array 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

#if !MIN_VERSION_primitive(0,7,1)
instance NFData a => NFData (Array a) where
    {-# INLINE rnf #-}
    rnf = foldl' (\_ x -> rnf x) ()
#endif

{-# INLINE fromStreamN #-}
fromStreamN :: MonadIO m => Int -> SerialT m a -> m (Array a)
fromStreamN :: Int -> SerialT m a -> m (Array 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 (Array a)
forall (m :: * -> *) a.
MonadIO m =>
Int -> Stream m a -> m (Array a)
fromStreamDN Int
n (Stream m a -> m (Array a)) -> Stream m a -> m (Array 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 => SerialT m a -> m (Array a)
fromStream :: SerialT m a -> m (Array a)
fromStream SerialT m a
m = Stream m a -> m (Array a)
forall (m :: * -> *) a. MonadIO m => Stream m a -> m (Array a)
fromStreamD (Stream m a -> m (Array a)) -> Stream m a -> m (Array 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 :: (Monad m, IsStream t) => Array a -> t m a
toStream :: Array 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)
-> (Array a -> Stream m a) -> Array a -> t m a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Array a -> Stream m a
forall (m :: * -> *) a. Monad m => Array a -> Stream m a
toStreamD

{-# INLINE_EARLY toStreamRev #-}
toStreamRev :: (Monad m, IsStream t) => Array a -> t m a
toStreamRev :: Array 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)
-> (Array a -> Stream m a) -> Array a -> t m a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Array a -> Stream m a
forall (m :: * -> *) a. Monad m => Array a -> Stream m a
toStreamDRev

{-# INLINE fold #-}
fold :: Monad m => Fold m a b -> Array a -> m b
fold :: Fold m a b -> Array a -> m b
fold Fold m a b
f Array 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 (Array a -> Stream m a
forall (m :: * -> *) a. Monad m => Array a -> Stream m a
toStreamD Array a
arr)

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

{-# INLINE_NORMAL read #-}
read :: Monad m => Unfold m (Array a) a
read :: Unfold m (Array a) a
read = ((Array a, Int) -> m (Step (Array a, Int) a))
-> (Array a -> m (Array a, Int)) -> Unfold m (Array a) a
forall (m :: * -> *) a b s.
(s -> m (Step s b)) -> (a -> m s) -> Unfold m a b
Unfold (Array a, Int) -> m (Step (Array a, Int) a)
forall (m :: * -> *) a.
Monad m =>
(Array a, Int) -> m (Step (Array a, Int) a)
step Array a -> m (Array 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 :: (Array a, Int) -> m (Step (Array a, Int) a)
step (Array a
arr, Int
i)
        | Int
i Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Array a -> Int
forall a. Array a -> Int
length Array a
arr = Step (Array a, Int) a -> m (Step (Array a, Int) a)
forall (m :: * -> *) a. Monad m => a -> m a
return Step (Array a, Int) a
forall s a. Step s a
D.Stop
    step (Array a
arr, (I# Int#
i)) =
        Step (Array a, Int) a -> m (Step (Array a, Int) a)
forall (m :: * -> *) a. Monad m => a -> m a
return (Step (Array a, Int) a -> m (Step (Array a, Int) a))
-> Step (Array a, Int) a -> m (Step (Array a, Int) a)
forall a b. (a -> b) -> a -> b
$
        case Array# a -> Int# -> (# a #)
forall a. Array# a -> Int# -> (# a #)
Exts.indexArray# (Array a -> Array# a
forall a. Array a -> Array# a
array# Array a
arr) Int#
i of
            (# a
x #) -> a -> (Array a, Int) -> Step (Array a, Int) a
forall s a. a -> s -> Step s a
D.Yield a
x (Array a
arr, Int# -> Int
I# Int#
i Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1)