Skip to content

Commit 7f107a7

Browse files
author
DDC
committed
Added folds and foldsM.
1 parent 039e266 commit 7f107a7

File tree

7 files changed

+47
-9
lines changed

7 files changed

+47
-9
lines changed

TODO.md

-2
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,6 @@
99
- takeWhileM :: Monad m => (a -> m Bool) -> Stream (Of a) m r -> Stream (Of a) m ()
1010

1111
- Splitting and grouping functions (Streaming + Pipes only)
12-
- folds :: Monad m => (x -> a -> x) -> x -> (x -> b) -> FreeT (Producer a m) m r -> Producer b m r
13-
- foldsM :: Monad m => (x -> a -> m x) -> m x -> (x -> m b) -> FreeT (Producer a m) m r -> Producer b m r
1412
- breaks :: Monad m => (a -> Bool) -> Stream (Of a) m r -> Stream (Stream (Of a) m) m r
1513
- break :: Monad m => (a -> Bool) -> Stream (Of a) m r -> Stream (Of a) m (Stream (Of a) m r)
1614
- breakWhen :: Monad m => (x -> a -> x) -> x -> (x -> b) -> (b -> Bool) -> Stream (Of a) m r -> Stream (Of a) m (Stream (Of a) m r)

streamy-pipes/lib/Streamy/Pipes.hs

+8
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,8 @@ module Streamy.Pipes (
4242
, Streamy.Pipes.intercalates
4343
, Streamy.Pipes.yields
4444
, Streamy.Pipes.takes
45+
, Streamy.Pipes.folds
46+
, Streamy.Pipes.foldsM
4547
, Streamy.Pipes.splitAt
4648
, Streamy.Pipes.span
4749
) where
@@ -185,6 +187,12 @@ yields producer = Groups $ liftF producer
185187
takes :: Monad m => Int -> Groups a m () -> Groups a m ()
186188
takes i (Groups gs) = Groups $ PG.takes i gs
187189

190+
folds :: Monad m => (x -> a -> x) -> x -> (x -> b) -> Groups a m r -> Stream b m r
191+
folds step begin done (Groups gs) = PG.folds step begin done gs
192+
193+
foldsM :: Monad m => (x -> a -> m x) -> m x -> (x -> m b) -> Groups a m r -> Stream b m r
194+
foldsM step begin done (Groups gs) = PG.foldsM step begin done gs
195+
188196
splitAt :: Monad m => Int -> Stream a m r -> Stream a m (Stream a m r)
189197
splitAt i producer = view (Pipes.Parse.splitAt i) producer
190198

streamy-sig/README.md

+2
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,8 @@ matrix saying which functions are supported by which libraries.
9292
| intercalates | X | X | |
9393
| yields | X | X | |
9494
| takes | X | X | |
95+
| folds | X | X | |
96+
| foldsM | X | X | |
9597
| splitAt | X | X | |
9698
| span | X | X | |
9799

streamy-sig/sig/Streamy.hsig

+3
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,9 @@ yields :: Monad m => Stream a m r -> Groups a m r
108108

109109
takes :: Monad m => Index -> Groups a m () -> Groups a m ()
110110

111+
folds :: Monad m => (x -> a -> x) -> x -> (x -> b) -> Groups a m r -> Stream b m r
112+
foldsM :: Monad m => (x -> a -> m x) -> m x -> (x -> m b) -> Groups a m r -> Stream b m r
113+
111114
splitAt :: Monad m => Index -> Stream a m r -> Stream a m (Stream a m r)
112115

113116
span :: Monad m => (a -> Bool) -> Stream a m r -> Stream a m (Stream a m r)

streamy-streaming/lib/Streamy/Streaming.hs

+15-7
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@ module Streamy.Streaming (
4343
, Streamy.Streaming.intercalates
4444
, Streamy.Streaming.yields
4545
, Streamy.Streaming.takes
46+
, Streamy.Streaming.folds
47+
, Streamy.Streaming.foldsM
4648
, Streamy.Streaming.splitAt
4749
, Streamy.Streaming.span
4850
) where
@@ -82,7 +84,7 @@ each :: (Monad m, Foldable f) => f a -> Stream a m ()
8284
each x = Stream (Q.each x)
8385

8486
toList :: Monad m => Stream a m r -> m ([a],r)
85-
toList (Stream s) = toTup <$> Q.toList s
87+
toList (Stream s) = Q.lazily <$> Q.toList s
8688

8789
toList_ :: Monad m => Stream a m () -> m [a]
8890
toList_ (Stream s) = Q.toList_ s
@@ -145,13 +147,13 @@ any_ :: Monad m => (a -> Bool) -> Stream a m () -> m Bool
145147
any_ f (Stream s) = Q.any_ f s
146148

147149
fold :: Monad m => (x -> a -> x) -> x -> (x -> b) -> Stream a m r -> m (b,r)
148-
fold step begin done (Stream s) = toTup <$> Q.fold step begin done s
150+
fold step begin done (Stream s) = Q.lazily <$> Q.fold step begin done s
149151

150152
fold_ :: Monad m => (x -> a -> x) -> x -> (x -> b) -> Stream a m () -> m b
151153
fold_ step begin done (Stream s) = Q.fold_ step begin done s
152154

153155
foldM :: Monad m => (x -> a -> m x) -> m x -> (x -> m b) -> Stream a m r -> m (b,r)
154-
foldM step begin done (Stream s) = toTup <$> Q.foldM step begin done s
156+
foldM step begin done (Stream s) = Q.lazily <$> Q.foldM step begin done s
155157

156158
foldM_ :: Monad m => (x -> a -> m x) -> m x -> (x -> m b) -> Stream a m () -> m b
157159
foldM_ step begin done (Stream s) = Q.foldM_ step begin done s
@@ -186,13 +188,19 @@ yields (Stream s) = Groups $ Q.yields s
186188
takes :: Monad m => Int -> Groups a m () -> Groups a m ()
187189
takes i (Groups gs) = Groups $ Q.takes i gs
188190

191+
folds :: Monad m => (x -> a -> x) -> x -> (x -> b) -> Groups a m r -> Stream b m r
192+
folds step begin done (Groups gs) =
193+
-- https://stackoverflow.com/questions/45773251/how-to-implement-folds-and-foldsm-from-pipes-group-for-the-streaming-package
194+
Stream $ Q.mapped (Q.fold step begin done) gs
195+
196+
foldsM :: Monad m => (x -> a -> m x) -> m x -> (x -> m b) -> Groups a m r -> Stream b m r
197+
foldsM step begin done (Groups gs) =
198+
-- https://stackoverflow.com/questions/45773251/how-to-implement-folds-and-foldsm-from-pipes-group-for-the-streaming-package
199+
Stream $ Q.mapped (Q.foldM step begin done) gs
200+
189201
splitAt :: Monad m => Int -> Stream a m r -> Stream a m (Stream a m r)
190202
splitAt i (Stream s) = Stream <$> Stream (Q.splitAt i s)
191203

192204
span :: Monad m => (a -> Bool) -> Stream a m r -> Stream a m (Stream a m r)
193205
span f (Stream s) = Stream <$> Stream (Q.span f s)
194206

195-
--
196-
toTup :: Of a r -> (a,r)
197-
toTup = \(a :> r) -> (a,r)
198-

streamy-testsuite/lib/Test/Grouping.hs

+17
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ grouping =
2525
, testCase "intercalates" testIntercalates
2626
, testCase "yields" testYields
2727
, testCase "takes" testTakes
28+
, testCase "folds" testFolds
29+
, testCase "foldsM" testFoldsM
2830
, testCase "splitAt" testSplitAt
2931
, testCase "span" testSpan
3032
]
@@ -73,3 +75,18 @@ testSpan = do
7375
assertEqual "" "abc" str1
7476
assertEqual "" "defg" str2
7577

78+
testFolds :: Assertion
79+
testFolds = do
80+
r <- Y.toList_ . Y.folds (flip (:)) [] id . Y.group $ Y.each "aabbcc"
81+
assertEqual "" ["aa","bb","cc"] r
82+
83+
testFoldsM :: Assertion
84+
testFoldsM = do
85+
ref <- newIORef False
86+
r <- Y.toList_
87+
. Y.foldsM (\x i -> pure (i:x)) (return []) (\x -> writeIORef ref True *> pure x)
88+
. Y.group
89+
$ Y.each "aabbcc"
90+
assertEqual "" ["aa","bb","cc"] r
91+
ref' <- readIORef ref
92+
assertBool "effect" ref'

streamy-testsuite/lib/Test/Grouping/Streamy.hsig

+2
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@ signature Test.Grouping.Streamy (
3838
, intercalates
3939
, yields
4040
, takes
41+
, folds
42+
, foldsM
4143
, splitAt
4244
, span
4345
) where

0 commit comments

Comments
 (0)