@@ -72,10 +72,10 @@ module Streamly.Internal.Data.Array.Foreign
7272 -- , (!!)
7373 , getIndex
7474 , A.unsafeIndex -- XXX Rename to getIndexUnsafe??
75− -- , getIndexRev
75+ , getIndexRev
7676 , last -- XXX getIndexLast?
77− -- , getIndices
78− -- , getIndicesFromThenTo
77+ , getIndices
78+ , getIndicesFromThenTo
7979 -- , getIndicesFrom -- read from a given position to the end of file
8080 -- , getIndicesUpto -- read from beginning up to the given position
8181 -- , getIndicesFromTo
@@ -87,8 +87,8 @@ module Streamly.Internal.Data.Array.Foreign
8787 , null
8888
8989 -- * Search
90− -- , binarySearch
91− -- , findIndicesOf
90+ , binarySearch
91+ , findIndicesOf
9292 -- , findIndexOf
9393 -- , find
9494
@@ -117,11 +117,11 @@ where
117117
118118import Control.Monad (when)
119119import Control.Monad.IO.Class (MonadIO(..))
120+import Data.Functor.Identity (Identity)
120121#if !(MIN_VERSION_base(4,11,0))
121122import Data.Semigroup ((<>))
122123#endif
123124import Data.Word (Word8)
124−-- import Data.Functor.Identity (Identity)
125125import Foreign.C.String (CString)
126126import Foreign.ForeignPtr (castForeignPtr)
127127import Foreign.ForeignPtr.Unsafe (unsafeForeignPtrToPtr)
@@ -317,27 +317,31 @@ writeLastN n
317317-- Searching
318318-------------------------------------------------------------------------------
319319
320−{-
321−-- | Perform a binary search in the array to find an element.
322−bsearch :: a -> Array a -> Maybe Bool
323−bsearch = undefined
324−
325−-- | Perform a binary search in the array to find an element index.
326−{-# INLINE elemIndex #-}
327−bsearchIndex :: a -> Array a -> Maybe Int
328−bsearchIndex elem arr = undefined
320+-- | Given a sorted array, perform a binary search to find the given element.
321+-- Returns the index of the element if found.
322+--
323+-- /Unimplemented/
324+{-# INLINE binarySearch #-}
325+binarySearch :: a -> Array a -> Maybe Int
326+binarySearch = undefined
329327
330328-- find/findIndex etc can potentially be implemented more efficiently on arrays
331329-- compared to streams by using SIMD instructions.
330+-- We can also return a bit array instead.
332331
333−find :: (a -> Bool) -> Array a -> Bool
334−find = undefined
332+-- | Perform a linear search to find all the indices where a given element is
333+-- present in an array.
334+--
335+-- /Unimplemented/
336+findIndicesOf :: (a -> Bool) -> Unfold Identity (Array a) Int
337+findIndicesOf = undefined
335338
336−findIndex :: (a -> Bool) -> Array a -> Maybe Int
337−findIndex = undefined
339+{-
340+findIndexOf :: (a -> Bool) -> Array a -> Maybe Int
341+findIndexOf p = Unfold.fold Fold.head . Stream.unfold (findIndicesOf p)
338342
339−findIndices :: (a -> Bool) -> Array a -> Array Int
340−findIndices = undefined
343+find :: (a -> Bool) -> Array a -> Bool
344+find = Unfold.fold Fold.null . Stream.unfold (findIndicesOf p)
341345-}
342346
343347-------------------------------------------------------------------------------
@@ -391,49 +395,44 @@ getIndex arr i =
391395 then Just <$> peek elemPtr
392396 else return Nothing
393397
394−{-
395−-- | @readSlice arr i count@ streams a slice of the array @arr@ starting
396−-- at index @i@ and reading up to @count@ elements in the forward direction
397−-- ending at the index @i + count - 1@.
398−--
399−-- @since 0.7.0
400−{-# INLINE readSlice #-}
401−readSlice :: (IsStream t, Monad m, Storable a)
402− => Array a -> Int -> Int -> t m a
403−readSlice arr i len = undefined
404−
405−-- | @readSliceRev arr i count@ streams a slice of the array @arr@ starting at
406−-- index @i@ and reading up to @count@ elements in the reverse direction ending
407−-- at the index @i - count + 1@.
408−--
409−-- @since 0.7.0
410−{-# INLINE readSliceRev #-}
411−readSliceRev :: (IsStream t, Monad m, Storable a)
412− => Array a -> Int -> Int -> t m a
413−readSliceRev arr i len = undefined
414−-}
415−
416−{-
417−-- | @writeSlice arr i count stream@ writes a stream to the array @arr@
418−-- starting at index @i@ and writing up to @count@ elements in the forward
419−-- direction ending at the index @i + count - 1@.
420−--
421−-- @since 0.7.0
422−{-# INLINE writeSlice #-}
423−writeSlice :: (IsStream t, Monad m, Storable a)
424− => Array a -> Int -> Int -> t m a -> m (Array a)
425−writeSlice arr i len s = undefined
426−
427−-- | @writeSliceRev arr i count stream@ writes a stream to the array @arr@
428−-- starting at index @i@ and writing up to @count@ elements in the reverse
429−-- direction ending at the index @i - count + 1@.
430−--
431−-- @since 0.7.0
432−{-# INLINE writeSliceRev #-}
433−writeSliceRev :: (IsStream t, Monad m, Storable a)
434− => Array a -> Int -> Int -> t m a -> m (Array a)
435−writeSliceRev arr i len s = undefined
436−-}
398+-- | Given a stream of array indices, read the elements on those indices from
399+-- the supplied Array. An exception is thrown if an index is out of bounds.
400+--
401+-- This is the most general operation. We can implement other operations in
402+-- terms of this:
403+--
404+-- @
405+-- read =
406+-- let u = lmap (\arr -> (0, length arr - 1)) Unfold.enumerateFromTo
407+-- in Unfold.lmap f (getIndices arr)
408+--
409+-- readRev =
410+-- let i = length arr - 1
411+-- in Unfold.lmap f (getIndicesFromThenTo i (i - 1) 0)
412+-- @
413+--
414+-- /Unimplemented/
415+{-# INLINE getIndices #-}
416+getIndices :: Unfold m (Array a) Int -> Unfold m (Array a) a
417+getIndices = undefined
418+
419+-- | Unfolds @(from, then, to, array)@ generating a finite stream whose first
420+-- element is the array value from the index @from@ and the successive elements
421+-- are from the indices in increments of @then@ up to @to@. Index enumeration
422+-- can occur downwards or upwards depending on whether @then@ comes before or
423+-- after @from@.
424+--
425+-- @
426+-- getIndicesFromThenTo =
427+-- let f (from, next, to, arr) =
428+-- (Stream.enumerateFromThenTo from next to, arr)
429+-- in Unfold.lmap f getIndices
430+-- @
431+--
432+-- /Unimplemented/
433+{-# INLINE getIndicesFromThenTo #-}
434+getIndicesFromThenTo :: Unfold m (Int, Int, Int, Array a) a
435+getIndicesFromThenTo = undefined
437436
438437-------------------------------------------------------------------------------
439438-- Transform via stream operations