on master help sign in
Add "scan" for left scans
commit2248ae7d6be2dfb485683759cd29b3f8f7086327 authorAbhiroop Sarkar <asiamgenius@gmail.com> dateSat 10 Mar 2018, 03:21 (9 years ago) parent70a56d1
2 files changed+16
src/Streamly/Prelude.hs+14 test/Main.hs+2
src/Streamly/Prelude.hs+14
@@ -29,6 +29,7 @@ module Streamly.Prelude
2929 -- ** General Folds
3030 , foldr
3131 , foldrM
32+ , scan
3233 , foldl
3334 , foldlM
3435 , uncons
@@ -155,6 +156,19 @@ foldrM step acc m = go (toStream m)
155156 yield a (Just x) = step a (go x)
156157 in (runStream m1) Nothing stop yield
157158
159+-- | Scan left. A strict left fold which accumulates the result of its reduction steps inside a stream, from left.
160+{-# INLINE scan #-}
161+scan :: Streaming t => (x -> a -> x) -> x -> (x -> b) -> t m a -> t m b
162+scan step begin done m = cons (done begin) $ fromStream $ go (toStream m) begin
163+ where
164+ go m1 !acc = Stream $ \_ stp yld ->
165+ let stop = stp
166+ yield a Nothing = yld (done $ step acc a) Nothing
167+ yield a (Just x) =
168+ let s = step acc a
169+ in yld (done s) (Just (go x s))
170+ in runStream m1 Nothing stop yield
171+
158172-- XXX This more straightforward implementation of fold is almost twice as
159173-- costly as the implementation we are using! Need to figure out what's wrong
160174-- with it. Is it GHC that is not able to optimize this somehow? Or is it
test/Main.hs+2
@@ -666,6 +666,8 @@ streamOperations (stream, list, len) = do
666666 it "dropWhile < some" $ transform (A.dropWhile (< (len `div` 2)))
667667 (dropWhile (< (len `div` 2)))
668668
669+ it "scan left" $ transform (A.scan (+) 0 id) (scanl (+) 0)
670+
669671 -- Elimination
670672 it "foldl" $ elimination (A.foldl (+) 0 id) (foldl (+) 0)
671673 it "all" $ elimination (A.all even) (all even)