on fa9fa09 help sign in
91 lines 3.2 kB history raw
1-- |
2-- Module : Streamly.Internal.Data.MutArray
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.MutArray
10 (
11 -- * MutArray.Type module
12 module Streamly.Internal.Data.MutArray.Type
13 -- * MutArray module
14 , splitOn
15 , genSlicesFromLen
16 , getSlicesFromLen
17 , fromStream
18 -- * Unboxed IORef
19 , module Streamly.Internal.Data.IORef.Unboxed
20 )
21where
23#include "inline.hs"
25import Control.Monad.IO.Class (MonadIO(..))
26import Streamly.Internal.Data.Unbox (Unbox)
27import Streamly.Internal.Data.Stream (Stream)
28import Streamly.Internal.Data.Unfold.Type (Unfold(..))
30import qualified Streamly.Internal.Data.Stream as D
31import qualified Streamly.Internal.Data.Unfold as Unfold
33import Prelude hiding (foldr, length, read, splitAt)
34import Streamly.Internal.Data.MutArray.Type
35import Streamly.Internal.Data.IORef.Unboxed
37-- | Split the array into a stream of slices using a predicate. The element
38-- matching the predicate is dropped.
39--
40-- /Pre-release/
41{-# INLINE splitOn #-}
42splitOn :: (MonadIO m, Unbox a) =>
43 (a -> Bool) -> MutArray a -> Stream m (MutArray a)
44splitOn predicate arr =
45 fmap (\(i, len) -> getSliceUnsafe i len arr)
46 $ D.sliceOnSuffix predicate (read arr)
48-- | Generate a stream of array slice descriptors ((index, len)) of specified
49-- length from an array, starting from the supplied array index. The last slice
50-- may be shorter than the requested length depending on the array length.
51--
52-- /Pre-release/
53{-# INLINE genSlicesFromLen #-}
54genSlicesFromLen :: forall m a. (Monad m, Unbox a)
55 => Int -- ^ from index
56 -> Int -- ^ length of the slice
57 -> Unfold m (MutArray a) (Int, Int)
58genSlicesFromLen from len =
59 let fromThenTo n = (from, from + len, n - 1)
60 mkSlice n i = return (i, min len (n - i))
61 in Unfold.lmap length
62 $ Unfold.mapM2 mkSlice
63 $ Unfold.lmap fromThenTo Unfold.enumerateFromThenTo
65-- | Generate a stream of slices of specified length from an array, starting
66-- from the supplied array index. The last slice may be shorter than the
67-- requested length depending on the array length.
68--
69-- /Pre-release/
70{-# INLINE getSlicesFromLen #-}
71getSlicesFromLen :: forall m a. (Monad m, Unbox a)
72 => Int -- ^ from index
73 -> Int -- ^ length of the slice
74 -> Unfold m (MutArray a) (MutArray a)
75getSlicesFromLen from len =
76 let mkSlice arr (i, n) = return $ getSliceUnsafe i n arr
77 in Unfold.mapM2 mkSlice (genSlicesFromLen from len)
79-- | Create an 'Array' from a stream. This is useful when we want to create a
80-- single array from a stream of unknown size. 'writeN' is at least twice
81-- as efficient when the size is already known.
82--
83-- Note that if the input stream is too large memory allocation for the array
84-- may fail. When the stream size is not known, `chunksOf` followed by
85-- processing of indvidual arrays in the resulting stream should be preferred.
86--
87-- /Pre-release/
88{-# INLINE fromStream #-}
89fromStream :: (MonadIO m, Unbox a) => Stream m a -> m (MutArray a)
90fromStream = fromStreamD
91-- fromStream (Stream m) = P.fold write m