gpt4 book ai didi

haskell - 连接 Producer 和 Pipe 以提取结果

转载 作者:行者123 更新时间:2023-12-04 02:43:16 26 4
gpt4 key购买 nike

有一个类型为 Producer ByteString IO () 的生产者和一个类型为 Pipe ByteString a IO () 的管道,我如何编写一个效果,这将导致 IO a 什么时候运行?

这是我最好的尝试:

{-# LANGUAGE ScopedTypeVariables #-}
import Pipes
import Data.ByteString

run :: forall a. IO a
run = runEffect $
(undefined :: Producer ByteString IO ()) >-> (undefined :: Pipe ByteString a IO ())

失败并显示以下内容:

Couldn't match type `Void' with `()'
Expected type: IO a
Actual type: IO ()
In the expression:
runEffect
$ (undefined :: Producer ByteString IO ())
>-> (undefined :: Pipe ByteString a IO ())
In an equation for `run':
run
= runEffect
$ (undefined :: Producer ByteString IO ())
>-> (undefined :: Pipe ByteString a IO ())

最佳答案

通常,您需要将ProducerConsumer 组合起来,以获得可由runEffect 运行的Effect 。这不是你在这里得到的,但幸运的是,除了 runEffect 之外,还有更多方法可以消除 Proxy

总结一下我们所拥有的,这个组合以 Producer 结束。

pipe :: Producer a IO ()
pipe = (undefined :: Producer ByteString IO ()) >-> (undefined :: Pipe ByteString a IO ())

Pipes.Prelude 模块包含许多其他方法来消除 Producer,例如 Pipes.Prelude.last

last :: Monad m => Producer a m () -> m (Maybe a)

获取a的最通用方法可能是使用Pipes.Prelude.fold

fold :: Monad m => (x -> a -> x) -> x -> (x -> b) -> Producer a m () -> m b

这类似于 runEffect,只是它将 Producers 缩减为它们的底层 Monad。因为这就是我们所拥有的,所以它会很好用。下面是我们如何实现 Pipes.Prelude.head

slowHead = fold (\res a -> res <> First (Just a)) mempty getFirst

值得注意的是 slowHead 消耗了整个 Producer(因此执行了所有需要的效果)而 Pipes.Prelude.head只执行第一个。它更懒惰!

关于haskell - 连接 Producer 和 Pipe 以提取结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19414549/

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