on master help sign in
Add strip API to Array
b06596fRanjeet Kumar Ranjan
src/Streamly/Internal/Data/Array.hs+35
@@ -16,6 +16,7 @@ module Streamly.Internal.Data.Array
16 ( Array(..)
16 ( Array(..)
17
17
18 -- * Construction
18 -- * Construction
19+ , nil
19 , writeN
20 , writeN
20 , write
21 , write
21 , writeLastN
22 , writeLastN
@@ -44,6 +45,7 @@ module Streamly.Internal.Data.Array
44
45
45 -- * Random Access
46 -- * Random Access
46 , getIndexUnsafe
47 , getIndexUnsafe
48+ , strip
47 )
49 )
48where
50where
49
51
@@ -74,6 +76,12 @@ import Prelude hiding (foldr, length, read)
74bottomElement :: a
76bottomElement :: a
75bottomElement = undefined
77bottomElement = undefined
76
78
79+{-# NOINLINE nil #-}
80+nil :: Array a
81+nil = unsafePerformIO $ do
82+ marr <- liftIO $ newArray 0 bottomElement
83+ liftIO $ freezeArray marr 0 0
84+
77-------------------------------------------------------------------------------
85-------------------------------------------------------------------------------
78-- Construction - Folds
86-- Construction - Folds
79-------------------------------------------------------------------------------
87-------------------------------------------------------------------------------
@@ -278,3 +286,30 @@ writeLastN n
278 liftIO $ copyMutableArray arr' 0 (RB.arr rb) ref (n - ref)
286 liftIO $ copyMutableArray arr' 0 (RB.arr rb) ref (n - ref)
279 liftIO $ copyMutableArray arr' (n - ref) (RB.arr rb) 0 ref
287 liftIO $ copyMutableArray arr' (n - ref) (RB.arr rb) 0 ref
280 liftIO $ unsafeFreezeArray arr'
288 liftIO $ unsafeFreezeArray arr'
289+
290+-- XXX This is not efficient as it copies the array. We should support array
291+-- slicing so that we can just refer to the underlying array memory instead of
292+-- copying.
293+--
294+-- | Truncate the array at the beginning and end as long as the predicate
295+-- holds true.
296+strip :: (a -> Bool) -> Array a -> Array a
297+strip p arr =
298+ let lastIndex = length arr - 1
299+ indexR = getIndexR lastIndex -- last predicate failing index
300+ in if indexR == -1
301+ then nil
302+ else
303+ let indexL = getIndexL 0 -- first predicate failing index
304+ in if indexL == 0 && indexR == lastIndex
305+ then arr
306+ else cloneArray arr indexL (indexR - indexL + 1)
307+
308+ where
309+
310+ getIndexR idx
311+ | idx < 0 = idx
312+ | otherwise =
313+ if p (indexArray arr idx) then getIndexR (idx - 1) else idx
314+
315+ getIndexL idx = if p (indexArray arr idx) then getIndexL (idx + 1) else idx