使用Conduit,给出:
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 ()]
为什么没有记录任何输出?
Prelude> runConduit $ yieldMany [1..10] .| mapC show .| mapC print .| sinkList
Prelude>
我的期望是,对于[1..10]
的流,每个元素的String
,即show
,都会打印出来。
请解释此输出。
答案 0 :(得分:6)
管道的结果是monad中的IO ()
列表,而不是单个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 ()]
即使您将m
设置为IO
,结果也会导致IO [IO ()]
,因为[IO ()]
没有{Show
,因此无法显示{1}}实例。如果您添加>>= sequence_
:
(runConduit $ yieldMany [1..10] .| mapC show .| mapC print .| sinkList) >>= sequence_
但是,真正的问题是您使用mapC print
代替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
如果您使用mapC print
,则最终会得到Conduit a m (IO ())
。如果您使用mapMC print
,则最终会得到Conduit a IO ()
。后者将m
设置为IO
,第一个不设置。{/ p>
所以使用正确的组合子来实现monadic函数:
runConduit $ yieldMany [1..10] .| mapC show .| mapMC print .| sinkNull
-- ^
另外,如果你没有得到预期的结果,请检查GHCi中it
的类型。