@@ -15,45 +15,42 @@
15module Streamly.Internal.Data.Array
15module Streamly.Internal.Data.Array
16 ( Array(..)
16 ( Array(..)
18− , foldl'
18+ -- * Construction
35 , fromStreamDN
22 , fromStreamDN
36 , fromStreamD
23 , fromStreamD
38 , fromStreamN
24 , fromStreamN
39 , fromStream
25 , fromStream
41 , streamFold
41 , streamFold
46−import Prelude hiding (foldr, length, read)
47#if !MIN_VERSION_primitive(0,7,1)
46#if !MIN_VERSION_primitive(0,7,1)
48import Control.DeepSeq (NFData(..))
47import Control.DeepSeq (NFData(..))
50import Control.Monad (when)
49import Control.Monad (when)
51import Control.Monad.IO.Class (liftIO, MonadIO)
50import Control.Monad.IO.Class (liftIO, MonadIO)
52import Data.Functor.Identity (runIdentity)
51import Data.Functor.Identity (runIdentity)
53−import Data.Primitive.Array hiding (fromList, fromListN)
54import GHC.Base (Int(..))
52import GHC.Base (Int(..))
55import GHC.IO (unsafePerformIO)
53import GHC.IO (unsafePerformIO)
56−import qualified GHC.Exts as Exts
58import Streamly.Internal.Data.Fold.Type (Fold(..))
55import Streamly.Internal.Data.Fold.Type (Fold(..))
59import Streamly.Internal.Data.Stream.StreamK.Type (IsStream)
56import Streamly.Internal.Data.Stream.StreamK.Type (IsStream)
@@ -61,48 +58,20 @@ import Streamly.Internal.Data.Stream.Serial (SerialT)
61import Streamly.Internal.Data.Tuple.Strict (Tuple'(..), Tuple3'(..))
58import Streamly.Internal.Data.Tuple.Strict (Tuple'(..), Tuple3'(..))
62import Streamly.Internal.Data.Unfold.Type (Unfold(..))
59import Streamly.Internal.Data.Unfold.Type (Unfold(..))
61+import qualified GHC.Exts as Exts
64import qualified Streamly.Internal.Data.Fold.Type as FL
62import qualified Streamly.Internal.Data.Fold.Type as FL
65import qualified Streamly.Internal.Data.Stream.StreamD as D
63import qualified Streamly.Internal.Data.Stream.StreamD as D
65+import Data.Primitive.Array hiding (fromList, fromListN)
66+import Prelude hiding (foldr, length, read)
67{-# NOINLINE bottomElement #-}
68{-# NOINLINE bottomElement #-}
68bottomElement :: a
69bottomElement :: a
69bottomElement = undefined
70bottomElement = undefined
71−{-# INLINE_NORMAL toStreamD #-}
72+-------------------------------------------------------------------------------
72−toStreamD :: Monad m => Array a -> D.Stream m a
73+-- Construction - Folds
73−toStreamD arr = D.Stream step 0
74+-------------------------------------------------------------------------------
75− {-# INLINE_LATE step #-}
77− | i == length arr = return D.Stop
80− case Exts.indexArray# (array# arr) i of
81− (# x #) -> D.Yield x (I# i + 1)
84−length :: Array a -> Int
87−{-# INLINE_NORMAL toStreamDRev #-}
88−toStreamDRev :: Monad m => Array a -> D.Stream m a
89−toStreamDRev arr = D.Stream step (length arr - 1)
91− {-# INLINE_LATE step #-}
93− | i < 0 = return D.Stop
96− case Exts.indexArray# (array# arr) i of
97− (# x #) -> D.Yield x (I# i - 1)
99−{-# INLINE_NORMAL foldl' #-}
100−foldl' :: (b -> a -> b) -> b -> Array a -> b
101−foldl' f z arr = runIdentity $ D.foldl' f z $ toStreamD arr
103−{-# INLINE_NORMAL foldr #-}
104−foldr :: (a -> b -> b) -> b -> Array a -> b
105−foldr f z arr = runIdentity $ D.foldr f z $ toStreamD arr
107-- writeN n = S.evertM (fromStreamDN n)
76-- writeN n = S.evertM (fromStreamDN n)
108{-# INLINE_NORMAL writeN #-}
77{-# INLINE_NORMAL writeN #-}
@@ -138,6 +107,10 @@ write = Fold step initial extract
138 return $ FL.Partial $ Tuple3' marr (i + 1) capacity
107 return $ FL.Partial $ Tuple3' marr (i + 1) capacity
139 extract (Tuple3' marr len _) = liftIO $ freezeArray marr 0 len
108 extract (Tuple3' marr len _) = liftIO $ freezeArray marr 0 len
110+-------------------------------------------------------------------------------
111+-- Construction - from streams
112+-------------------------------------------------------------------------------
141{-# INLINE_NORMAL fromStreamDN #-}
114{-# INLINE_NORMAL fromStreamDN #-}
142fromStreamDN :: MonadIO m => Int -> D.Stream m a -> m (Array a)
115fromStreamDN :: MonadIO m => Int -> D.Stream m a -> m (Array a)
143fromStreamDN limit str = do
116fromStreamDN limit str = do
@@ -153,6 +126,16 @@ fromStreamDN limit str = do
153fromStreamD :: MonadIO m => D.Stream m a -> m (Array a)
126fromStreamD :: MonadIO m => D.Stream m a -> m (Array a)
154fromStreamD = D.fold write
127fromStreamD = D.fold write
129+{-# INLINE fromStreamN #-}
130+fromStreamN :: MonadIO m => Int -> SerialT m a -> m (Array a)
132+ when (n < 0) $ error "fromStreamN: negative write count specified"
133+ fromStreamDN n $ D.toStreamD m
135+{-# INLINE fromStream #-}
136+fromStream :: MonadIO m => SerialT m a -> m (Array a)
137+fromStream m = fromStreamD $ D.toStreamD m
156{-# INLINABLE fromListN #-}
139{-# INLINABLE fromListN #-}
157fromListN :: Int -> [a] -> Array a
140fromListN :: Int -> [a] -> Array a
158fromListN n xs = unsafePerformIO $ fromStreamDN n $ D.fromList xs
141fromListN n xs = unsafePerformIO $ fromStreamDN n $ D.fromList xs
@@ -161,21 +144,53 @@ fromListN n xs = unsafePerformIO $ fromStreamDN n $ D.fromList xs
161fromList :: [a] -> Array a
144fromList :: [a] -> Array a
162fromList xs = unsafePerformIO $ fromStreamD $ D.fromList xs
145fromList xs = unsafePerformIO $ fromStreamD $ D.fromList xs
164−#if !MIN_VERSION_primitive(0,7,1)
147+-------------------------------------------------------------------------------
165−instance NFData a => NFData (Array a) where
148+-- Elimination - Unfolds
166− {-# INLINE rnf #-}
149+-------------------------------------------------------------------------------
167− rnf = foldl' (\_ x -> rnf x) ()
170−{-# INLINE fromStreamN #-}
151+{-# INLINE length #-}
171−fromStreamN :: MonadIO m => Int -> SerialT m a -> m (Array a)
152+length :: Array a -> Int
172−fromStreamN n m = do
153+length = sizeofArray
173− when (n < 0) $ error "fromStreamN: negative write count specified"
174− fromStreamDN n $ D.toStreamD m
176−{-# INLINE fromStream #-}
155+{-# INLINE_NORMAL read #-}
177−fromStream :: MonadIO m => SerialT m a -> m (Array a)
156+read :: Monad m => Unfold m (Array a) a
178−fromStream m = fromStreamD $ D.toStreamD m
157+read = Unfold step inject
159+ inject arr = return (arr, 0)
161+ | i == length arr = return D.Stop
164+ case Exts.indexArray# (array# arr) i of
165+ (# x #) -> D.Yield x (arr, I# i + 1)
167+-------------------------------------------------------------------------------
168+-- Elimination - to streams
169+-------------------------------------------------------------------------------
171+{-# INLINE_NORMAL toStreamD #-}
172+toStreamD :: Monad m => Array a -> D.Stream m a
173+toStreamD arr = D.Stream step 0
175+ {-# INLINE_LATE step #-}
177+ | i == length arr = return D.Stop
180+ case Exts.indexArray# (array# arr) i of
181+ (# x #) -> D.Yield x (I# i + 1)
183+{-# INLINE_NORMAL toStreamDRev #-}
184+toStreamDRev :: Monad m => Array a -> D.Stream m a
185+toStreamDRev arr = D.Stream step (length arr - 1)
187+ {-# INLINE_LATE step #-}
189+ | i < 0 = return D.Stop
192+ case Exts.indexArray# (array# arr) i of
193+ (# x #) -> D.Yield x (I# i - 1)
180{-# INLINE_EARLY toStream #-}
195{-# INLINE_EARLY toStream #-}
181toStream :: (Monad m, IsStream t) => Array a -> t m a
196toStream :: (Monad m, IsStream t) => Array a -> t m a
@@ -185,6 +200,24 @@ toStream = D.fromStreamD . toStreamD
185toStreamRev :: (Monad m, IsStream t) => Array a -> t m a
200toStreamRev :: (Monad m, IsStream t) => Array a -> t m a
186toStreamRev = D.fromStreamD . toStreamDRev
201toStreamRev = D.fromStreamD . toStreamDRev
203+-------------------------------------------------------------------------------
204+-- Elimination - using Folds
205+-------------------------------------------------------------------------------
207+{-# INLINE_NORMAL foldl' #-}
208+foldl' :: (b -> a -> b) -> b -> Array a -> b
209+foldl' f z arr = runIdentity $ D.foldl' f z $ toStreamD arr
211+{-# INLINE_NORMAL foldr #-}
212+foldr :: (a -> b -> b) -> b -> Array a -> b
213+foldr f z arr = runIdentity $ D.foldr f z $ toStreamD arr
215+#if !MIN_VERSION_primitive(0,7,1)
216+instance NFData a => NFData (Array a) where
218+ rnf = foldl' (\_ x -> rnf x) ()
188{-# INLINE fold #-}
221{-# INLINE fold #-}
189fold :: Monad m => Fold m a b -> Array a -> m b
222fold :: Monad m => Fold m a b -> Array a -> m b
190fold f arr = D.fold f (toStreamD arr)
223fold f arr = D.fold f (toStreamD arr)
@@ -192,15 +225,3 @@ fold f arr = D.fold f (toStreamD arr)
192{-# INLINE streamFold #-}
225{-# INLINE streamFold #-}
193streamFold :: Monad m => (SerialT m a -> m b) -> Array a -> m b
226streamFold :: Monad m => (SerialT m a -> m b) -> Array a -> m b
194streamFold f arr = f (toStream arr)
227streamFold f arr = f (toStream arr)
196−{-# INLINE_NORMAL read #-}
197−read :: Monad m => Unfold m (Array a) a
198−read = Unfold step inject
200− inject arr = return (arr, 0)
202− | i == length arr = return D.Stop
205− case Exts.indexArray# (array# arr) i of
206− (# x #) -> D.Yield x (arr, I# i + 1)