如何将两个消费者合并成一个Haskell Pipes? [英] How to merge two Consumer into one in Haskell Pipes?

查看:116
本文介绍了如何将两个消费者合并成一个Haskell Pipes?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用Haskell流处理库管道编写命令行工具。每个命令行操作都可以将结果输出到 stdout ,并使用 pipes 记录到 stderr c $ c $> API。

我需要 Consumer ,其类型为 Consumer打印数据块( Left )至 stderr ,<$ c> $ c> Right stdout )与单个消费者



我写的代码(应该改进)



这个函数 consumeEither doesn'

  consumeEither ::(MonadIO m)=>所以我想改进它。消费者(或者字符串字符串)m()
consumeEither = do
或者S< - 等待
case $ s
(Left l) - > for(yield l)(liftIO。(IO.hPutStrLn IO.stderr))
(Right r) - > for(yiled r)(liftIO。putStrLn)

此外,提供一个函数会很有用两个消费者 s并将它们合并为一个消费者



问题



是否有人知道以下接口的良好示例或实现?

  merge ::(Monad m)=>消费者a m r  - >消费者b m r  - >消费者(或者ab)mr 




  • 第一个参数为 stderr

  • 第二个参数为 stdout



函数的用法



  import Pipes 
导入合格Pipes.Prelude作为P
将合格System.IO导入为IO
$ b stdoutOrErr :: Consumer(或者String String)IO()
stdoutOrErr = merge(P.toHandle IO.stderr)P.stdoutLn

谢谢



pipes-extras 。请记住消费者管道(无处),所以 P.toHandle IO .stderr +++ P.stdoutLn :: MonadIO m => Pipe(String String)(或bd)m()



获取 Consumer ,你必须去掉 Lefts ,例如用> - > P.concat > - > P.drain 。用 Fold s来做到这一点的方法更加健壮和美观。


I use Haskell stream processing library pipes to write a command line tool. Each command line actions may output result to stdout and logs to stderr with pipes API.

I need Consumer which has type as Consumer (Either String String) m r to print chunk of data (Left to stderr, Right to stdout) with single Consumer.

Code I wrote (should be improved)

This function consumeEither doesn't have flexibility so I want to improve it.

consumeEither :: (MonadIO m) => Consumer (Either String String) m ()
consumeEither = do
  eitherS <- await
  case eitherS of
    (Left l)  -> for (yield l) (liftIO . (IO.hPutStrLn IO.stderr))
    (Right r) -> for (yiled r) (liftIO . putStrLn)

Furthermore it would be useful to provide a function which takes two Consumers and merge them into one Consumer.

Question

Does anybody know good example or implementation of the following interface?

merge :: (Monad m) => Consumer a m r -> Consumer b m r -> Consumer (Either a b) m r

  • 1st argument as stderr
  • 2nd argument as stdout

Usage of the function

import           Pipes
import qualified Pipes.Prelude as P
import qualified System.IO as IO

stdoutOrErr :: Consumer (Either String String) IO ()
stdoutOrErr = merge (P.toHandle IO.stderr) P.stdoutLn

Thanks

解决方案

(This is @Michael's answer, but I'd like to write it up here so we can move the question out of the unanswered queue for the Haskell tag.)

See (+++) in pipes-extras. Keep in mind a Consumer is a Pipe (to nowhere), so P.toHandle IO.stderr +++ P.stdoutLn :: MonadIO m => Pipe (Either String String) (Either b d) m ().

To get a Consumer, you would have to get rid of the Lefts e.g with >-> P.concat or >-> P.drain. There are more robust and handsome ways of doing this with Folds.

这篇关于如何将两个消费者合并成一个Haskell Pipes?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆