on master help sign in
Merge branch 'Abhiroop-prelude-functions'
56fd321Harendra Kumar
Changelog.md+1
@@ -1,6 +1,7 @@
1## Unreleased
1## Unreleased
2
2
3* Performance improvements of several stream operations
3* Performance improvements of several stream operations
4+* Addition of scan function to the prelude
4
5
5## 0.1.0
6## 0.1.0
6
7
src/Streamly/Prelude.hs+14
@@ -29,6 +29,7 @@ module Streamly.Prelude
29 -- ** General Folds
29 -- ** General Folds
30 , foldr
30 , foldr
31 , foldrM
31 , foldrM
32+ , scan
32 , foldl
33 , foldl
33 , foldlM
34 , foldlM
34 , uncons
35 , uncons
@@ -155,6 +156,19 @@ foldrM step acc m = go (toStream m)
155 yield a (Just x) = step a (go x)
156 yield a (Just x) = step a (go x)
156 in (runStream m1) Nothing stop yield
157 in (runStream m1) Nothing stop yield
157
158
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+
158-- XXX This more straightforward implementation of fold is almost twice as
172-- XXX This more straightforward implementation of fold is almost twice as
159-- costly as the implementation we are using! Need to figure out what's wrong
173-- costly as the implementation we are using! Need to figure out what's wrong
160-- with it. Is it GHC that is not able to optimize this somehow? Or is it
174-- 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
666 it "dropWhile < some" $ transform (A.dropWhile (< (len `div` 2)))
666 it "dropWhile < some" $ transform (A.dropWhile (< (len `div` 2)))
667 (dropWhile (< (len `div` 2)))
667 (dropWhile (< (len `div` 2)))
668
668
669+ it "scan left" $ transform (A.scan (+) 0 id) (scanl (+) 0)
670+
669 -- Elimination
671 -- Elimination
670 it "foldl" $ elimination (A.foldl (+) 0 id) (foldl (+) 0)
672 it "foldl" $ elimination (A.foldl (+) 0 id) (foldl (+) 0)
671 it "all" $ elimination (A.all even) (all even)
673 it "all" $ elimination (A.all even) (all even)