Reputation: 41909
Using Conduit, given:
Prelude> :t (yieldMany [1..10] .| mapC show .| mapC print .| sinkList)
(yieldMany [1..10] .| mapC show .| mapC print .| sinkList)
:: Monad m => ConduitM a c m [IO ()]
Why doesn't any output get logged?
Prelude> runConduit $ yieldMany [1..10] .| mapC show .| mapC print .| sinkList
Prelude>
My expectation was that, for a stream of [1..10]
, each element's String
, i.e. show
, value would be printed.
Please explain this output.
Upvotes: 2
Views: 195
Reputation: 105876
The result of the conduit is a list of IO ()
in a monad, not a single IO ()
:
Prelude Conduit> :t runConduit $ yieldMany [1..10] .| mapC show .| mapC print .| sinkList
runConduit $ yieldMany [1..10] .| mapC show .| mapC print .| sinkList
:: Monad m => m [IO ()]
Even if you set m
to IO
, you end up with IO [IO ()]
as result, which doesn't get shown because [IO ()]
does not have a Show
instance. You can fix that if you add >>= sequence_
:
(runConduit $ yieldMany [1..10] .| mapC show .| mapC print .| sinkList) >>= sequence_
However, the real problem is that you use mapC print
instead of mapMC print
:
Prelude Conduit> :t mapC
mapC :: Monad m => (a -> b) -> Conduit a m b
Prelude Conduit> :t mapMC
mapMC :: Monad m => (a -> m b) -> Conduit a m b
If you use mapC print
, you end up with Conduit a m (IO ())
. If you use mapMC print
, you end up with Conduit a IO ()
. The latter sets m
to IO
, the first does not.
So use the correct combinator for monadic functions:
runConduit $ yieldMany [1..10] .| mapC show .| mapMC print .| sinkNull
-- ^
Also, check the type of it
in GHCi if you don't get the expected result.
Upvotes: 6