on 4300a9f help sign in
86 lines 3.1 kB history raw
1-- |
2-- Module : Streamly.Internal.Data.Array.Mut
3-- Copyright : (c) 2020 Composewell Technologies
4-- License : BSD-3-Clause
5-- Maintainer : streamly@composewell.com
6-- Stability : experimental
7-- Portability : GHC
8--
9module Streamly.Internal.Data.Array.Mut
10 (
11 module Streamly.Internal.Data.Array.Mut.Type
12 , splitOn
13 , genSlicesFromLen
14 , getSlicesFromLen
15 , fromStream
16 )
17where
19#include "inline.hs"
21import Control.Monad.IO.Class (MonadIO(..))
22import Streamly.Internal.Data.Unboxed (Unbox)
23import Streamly.Internal.Data.Stream.StreamD (Stream)
24import Streamly.Internal.Data.Unfold.Type (Unfold(..))
26import qualified Streamly.Internal.Data.Stream.StreamD as D
27import qualified Streamly.Internal.Data.Unfold as Unfold
29import Prelude hiding (foldr, length, read, splitAt)
30import Streamly.Internal.Data.Array.Mut.Type
32-- | Split the array into a stream of slices using a predicate. The element
33-- matching the predicate is dropped.
34--
35-- /Pre-release/
36{-# INLINE splitOn #-}
37splitOn :: (MonadIO m, Unbox a) =>
38 (a -> Bool) -> MutArray a -> Stream m (MutArray a)
39splitOn predicate arr =
40 fmap (\(i, len) -> getSliceUnsafe i len arr)
41 $ D.sliceOnSuffix predicate (toStreamD arr)
43-- | Generate a stream of array slice descriptors ((index, len)) of specified
44-- length from an array, starting from the supplied array index. The last slice
45-- may be shorter than the requested length depending on the array length.
46--
47-- /Pre-release/
48{-# INLINE genSlicesFromLen #-}
49genSlicesFromLen :: forall m a. (Monad m, Unbox a)
50 => Int -- ^ from index
51 -> Int -- ^ length of the slice
52 -> Unfold m (MutArray a) (Int, Int)
53genSlicesFromLen from len =
54 let fromThenTo n = (from, from + len, n - 1)
55 mkSlice n i = return (i, min len (n - i))
56 in Unfold.lmap length
57 $ Unfold.mapM2 mkSlice
58 $ Unfold.lmap fromThenTo Unfold.enumerateFromThenTo
60-- | Generate a stream of slices of specified length from an array, starting
61-- from the supplied array index. The last slice may be shorter than the
62-- requested length depending on the array length.
63--
64-- /Pre-release/
65{-# INLINE getSlicesFromLen #-}
66getSlicesFromLen :: forall m a. (Monad m, Unbox a)
67 => Int -- ^ from index
68 -> Int -- ^ length of the slice
69 -> Unfold m (MutArray a) (MutArray a)
70getSlicesFromLen from len =
71 let mkSlice arr (i, n) = return $ getSliceUnsafe i n arr
72 in Unfold.mapM2 mkSlice (genSlicesFromLen from len)
74-- | Create an 'Array' from a stream. This is useful when we want to create a
75-- single array from a stream of unknown size. 'writeN' is at least twice
76-- as efficient when the size is already known.
77--
78-- Note that if the input stream is too large memory allocation for the array
79-- may fail. When the stream size is not known, `chunksOf` followed by
80-- processing of indvidual arrays in the resulting stream should be preferred.
81--
82-- /Pre-release/
83{-# INLINE fromStream #-}
84fromStream :: (MonadIO m, Unbox a) => Stream m a -> m (MutArray a)
85fromStream = fromStreamD
86-- fromStream (Stream m) = P.fold write m