I am exploring the possibility to use the Conduit package in order to implement complex event processing in Haskell. As an example, I would like to implement an accumulating function using Conduit.
Starting from:
#!/usr/bin/env stack
-- stack script --resolver lts-8.12 --package conduit-combinators
{-# LANGUAGE ExtendedDefaultRules #-}
import Conduit
trans :: Monad m => ConduitM Int Int m ()
trans = do
mapC (* 2)
main :: IO ()
main = runConduit $ yieldMany [1..10] .| trans .| mapM_C print
I get:
2 4 6 8 10 12 14 16 18 20
How can I modify trans so that it yields
1 3 6 10 15 21 28 36 45 55
instead?
scanlC, which is an "analog of scanl for lists", does almost what you want. I say "almost" because scanlC asks for and yields an initial "seed" value, which you don't need nor want (cf. the difference between scanl and scanl1). That being so, you will need to explicitly feed the first streamed value as the seed:
trans :: Monad m => ConduitM Int Int m ()
trans = await >>= maybe (return ()) (scanlC (+))
(The -- clearly inferior -- alternative would be having trans = scanlC (+) 0 and using dropC 1 in the next step of the pipeline to get rid of the 0.)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With