首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在管道中使用管道丢弃功能?

如何在管道中使用管道丢弃功能?
EN

Stack Overflow用户
提问于 2012-05-31 21:37:53
回答 1查看 536关注 0票数 9

我有一个简单的任务-从文件中读取一堆行,并对每一行执行一些操作。除了第一个--这是一些可以忽略的标题。

所以我想我应该试试管道。

代码语言:javascript
复制
printFile src = runResourceT $ CB.sourceFile src =$= 
    CT.decode CT.utf8 =$= CT.lines =$= CL.mapM_ putStrLn

凉爽的。

所以现在我只想把第一行...似乎有一个函数可以解决这个问题-

代码语言:javascript
复制
printFile src = runResourceT $ CB.sourceFile src =$= 
    CT.decode CT.utf8 =$= CT.lines =$= drop 1 =$= CL.mapM_ putStrLn

嗯-但是现在我注意到drop有类型签名Sink a m ()。有人建议我可以使用管道的Monad实例,并使用drop有效地删除一些元素-所以我尝试了以下方法:

代码语言:javascript
复制
drop' :: Int -> Pipe a a m ()
drop' n = do
  CL.drop n
  x <- await
  case x of 
    Just v -> yield v
    Nothing -> return ()

它不会进行类型检查,因为管道的monad实例只适用于相同类型的管道- Sinks的输出是Void,所以我不能这样使用它。

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

所以我很困惑--也许我遗漏了一个关键概念..我看到了这个函数

代码语言:javascript
复制
sequence ::  Sink input m output -> Conduit input m output

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

代码语言:javascript
复制
CL.sequence (CL.drop 1) :: Conduit a m ()    

我可能只会回去使用lazy-io,因为我并不真的需要任何流媒体--但我很有兴趣看看正确的方法。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2012-05-31 23:21:19

首先,简单的回答:

代码语言:javascript
复制
... =$= CT.lines =$= (CL.drop 1 >> CL.mapM_ putStrLn)

更详细的解释是:实际上有两种不同的方法可以实现drop。无论采用哪种方法,它都会首先从输入中删除n元素。关于它的下一步操作,有两种选择:

  • 表示已完成
  • 开始输出输入流

中的所有剩余项

前者是Sink将执行的行为(以及我们的drop实际执行的操作),而后者是Conduit的行为。实际上,您可以通过一元组合从前者生成后者:

代码语言:javascript
复制
dropConduit n = CL.drop n >> CL.map id

然后,您可以使用dropConduit,正如您在开头所描述的。这是演示一元合成和融合之间区别的一种好方法;前者允许两个函数在同一个输入流上操作,而后者允许一个函数向另一个函数提供流。

我还没有进行基准测试,但我相当确定一元组合将会更有效率。

票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/10834773

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档