使用管道,给定:
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
,值将是打印出来。
请解释这个输出。
最佳答案
管道的结果是 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
实例。如果添加 >>= 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
,而第一个则没有。
所以对单子(monad)函数使用正确的组合器:
runConduit $ yieldMany [1..10] .| mapC show .| mapMC print .| sinkNull
-- ^
此外,如果您没有得到预期的结果,请检查 GHCi 中 it
的类型。
关于haskell - 了解 `conduit` 输出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44327727/