如何使用管道降功能的管道?(How to use the conduit drop function

2019-07-29 15:46发布

我有一个简单的任务 - 读了一堆线条勾勒出一个文件,并与他们每个人的东西。 除了第一个 - 这是一些标题被忽略。

所以,我想我会尝试的管道。

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

嗯-但现在我发现有滴类型签名Sink am () 有人建议,我认为我可以使用管道和使用降单子实例effectfully下降一些元素 - 所以我尝试这样做:

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

不键入检查,因为管道的单子实例只适用于同一类型的管道 - 汇有空隙,例如它们的输出,所以我不能这样使用它。

我刚刚看了一下,在管材,管芯和我注意到,管芯有,我希望它是功能,其中如管道是一个很小的库,但文档显示它如何执行。

所以我很困惑 - 也许有我缺少一个关键的概念。我看到了功能

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

但是,这似乎并没有被正确的想法,作为输出值是()

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

我可能就回去使用懒惰-io的,因为我并不需要任何流 - 但我很想看到正确的方式做到这一点。

Answer 1:

首先,简单的答案:

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

较长的解释:实际上有两种不同的方式可以实现drop 。 无论哪种方式,将第一下降n从输入元件。 大约有它的作用下两个选择:

  • 说,它的完成
  • 开始从输入流输出所有剩余项目的

前者的行为是什么Sink将执行(以及我们drop实际上没有),而后者则是行为Conduit 。 您可以在事实上产生来自前者通过单子组成后者:

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

然后你可以使用dropConduit你描述开头。 这是展示一元组合物和熔化之间的差的一个很好的方法; 前者允许两个功能上相同的输入流进行操作,而后者则允许一个功能以供给流至另一个。

我没有基准,但我相当肯定,单子成分会多一点效率。



文章来源: How to use the conduit drop function in a pipeline?