I'm adding a new answer because I've fixed this issue in pipes-3.3
, which I just uploaded to Hackage. The theory behind pipes shows that the global behavior you were expecting was the right behavior all along, and WriterP
now behaves globally so you can fold within a pipe.
I've modified your example to show you would implement it using pipes-3.3
:
import Control.Proxy
import Control.Proxy.Trans.Writer
main = do
let source = enumFromToS (0::Int) 5
a <- runProxy $ execWriterK $ source >-> sumD
print a
You can also now retrieve the results of a fold within a pipeline. For example, this is perfectly valid:
chunksOf :: (Monad m, Proxy p) => Int -> () -> Pipe p a [a] m r
chunksOf n () = runIdentityP $ forever $ do
-- The unitU discards the values that 'toListD' reforwards
as <- execWriterK (takeB_ n >-> toListD >-> unitU) ()
respond as
Here's an example usage:
>>> runProxy $ getLineS >-> takeWhileD (/= "quit") >-> chunksOf 3 >-> printD
1<Enter>
2<Enter>
3<Enter>
["1","2","3"]
4<Enter>
5<Enter>
6<Enter>
["4","5","6"]
quit
Sorry for getting the answer wrong the first time!