gpt4 book ai didi

haskell - 了解 `conduit` 输出

转载 作者:行者123 更新时间:2023-12-02 08:13:05 25 4
gpt4 key购买 nike

使用管道,给定:

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/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com