如何在管道中使用导管放置功能? [英] How to use the conduit drop function in a pipeline?

查看:213
本文介绍了如何在管道中使用导管放置功能?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个简单的任务 - 从一个文件中读出一堆行,并对其中的每一行进行一些操作。所以我想我会尝试管道。



除了第一个 - 这是一些标题要被忽略。

  printFile src = runResourceT $ CB.sourceFile src = $ = 
CT.decode CT.utf8 = $ = CT.lines = $ = CL.mapM_ putStrLn

酷。



所以现在我只想放弃第一行关闭...并且似乎有一个函数 -

  printFile src = runResourceT $ CB.sourceFile src = $ = 
CT.decode CT.utf8 = $ = CT.lines = $ = drop 1 = $ = CL.mapM_ putStrLn



< - >嗯 - 但现在我注意到drop有类型签名 Sink am()。有人向我建议,我可以使用Monad实例管道,并使用drop来有效地删除一些元素 - 所以我试过了:

  drop':: Int  - >管a a m()
drop'n = do
CL.drop n
x < - 等待
case x of
Just v - >收益v
无 - >返回()

其中不检查类型,因为管道的monad实例仅适用于相同类型 - 接收器的输出为无效,所以我不能像这样使用它。



我快速浏览了管道和管道,我注意到pipes-core具有我期望的功能,其中管道是一个最小的库,但文档显示了它将如何实现。



所以我很困惑 - 也许有一个关键的概念,我失踪了..我看到了功能

  sequence:Sink input m output  - > Conduit input m output 

但是这似乎不是正确的想法,因为输出值是()

  CL.sequence(CL.drop 1):: Conduit am()

我可能会回去使用lazy-io,因为我真的不需要任何流媒体 - 但我有兴趣看到

解决方案

首先,简单的回答:

  ... = $ = CT.lines = $ =(CL.drop 1>>> CL.mapM_ putStrLn)

更长的解释:实际上有两种不同的方式可以实现 drop 。无论哪种方式,它都会首先从输入中删除 n 元素。接下来有两种选择:


  • 说完成

  • 开始输出全部输入流中的其余项



以前的行为是 Sink 会执行(以及我们的 drop 实际上是这样做的),而后者则是 Conduit 的行为。实际上,你可以通过一元构成从前者生成后者:

  dropConduit n = CL.drop n>> CL.map id 

然后您可以使用 dropConduit 正如你在开头描述的那样。这是证明单子组成和融合之间区别的一种好方法;前者允许两个函数在同一个输入流上操作,而后者则允许一个函数向另一个输入流。



我没有基准测试,但是我我相当肯定,一元组合会更有效率。

I have a simple task - read a bunch of lines out of a file and do something with each one of them. Except the first one - which are some headings to be ignored.

So I thought I'd try out conduits.

printFile src = runResourceT $ CB.sourceFile src =$= 
    CT.decode CT.utf8 =$= CT.lines =$= CL.mapM_ putStrLn

Cool.

So now I just want to drop the first line off ... and there seems to be a function for that -

printFile src = runResourceT $ CB.sourceFile src =$= 
    CT.decode CT.utf8 =$= CT.lines =$= drop 1 =$= CL.mapM_ putStrLn

Hmm - but now I notice drop has type signature Sink a m (). Someone suggested to me that I can use the Monad instance for pipes and use drop to effectfully drop some elements - so I tried this:

drop' :: Int -> Pipe a a m ()
drop' n = do
  CL.drop n
  x <- await
  case x of 
    Just v -> yield v
    Nothing -> return ()

Which doesn't type check because the monad instance for pipes only applies to pipes of the same type - Sinks have Void as their output, so I can't use it like this.

I took a quick look at pipes and pipes-core and I notice that pipes-core has the function as I expected it to be, where as pipes is a minimal library but the documentation shows how it would be implemented.

So I'm confused - maybe there's a key concept I'm missing .. I saw the function

sequence ::  Sink input m output -> Conduit input m output

But that doesn't seem to be the right idea, as the output value is ()

CL.sequence (CL.drop 1) :: Conduit a m ()    

I'll probably just go back and use lazy-io as I don't really need any streaming - but I'd be interested to see the proper way to do it.

解决方案

Firstly, the simple answer:

... =$= CT.lines =$= (CL.drop 1 >> CL.mapM_ putStrLn)

The longer explanation: there are really two different ways you can implement drop. Either way, it will first drop n elements from the input. There are two choices about what it does next:

  • Says it's done
  • Start outputting all of the remaining items from the input stream

The former behavior is what a Sink would perform (and what our drop actually does) while the latter is the behavior of a Conduit. You can in fact generate the latter from the former through monadic composition:

dropConduit n = CL.drop n >> CL.map id

Then you can use dropConduit as you describe at the beginning. This is a good way of demonstrating the difference between monadic composition and fusing; the former allows two functions to operate on the same input stream, while the latter allows one function to feed a stream to the other.

I haven't benchmarked, but I'm fairly certain that monadic composition will be a bit more efficient.

这篇关于如何在管道中使用导管放置功能?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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