连接Producer和Pipe以提取结果

时间:2013-10-16 21:48:48

标签: haskell pipe haskell-pipes

拥有类型为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 ())

1 个答案:

答案 0 :(得分:4)

通常,您需要使用Producer撰写Consumer才能获得Effect runEffect。这不是你在这里得到的,但幸运的是,有更多方法可以消除Proxy,而不仅仅是runEffect

总结一下Producer

评估我们所拥有的内容
pipe :: Producer a IO ()
pipe = (undefined :: Producer ByteString IO ()) >-> (undefined :: Pipe ByteString a IO ()) 

Pipes.Prelude模块包含许多其他消除Producers的{​​{1}}的方法

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只执行第一个。{1}}。它太懒了!