保留管道流的每个第n个元素

时间:2016-12-15 17:20:16

标签: haskell conduit

我使用Conduit以类似流的方式解析某些数据。在流中的某个点上,我需要每12个元素。有没有方便的方法呢?

我目前明确等待12个元素只是为了返回第一个元素:

get12th :: Monad m => Conduit Int m Int
get12th = loop
  where
    loop = do
        v1 <- await
        _ <- await
        _ <- await
        _ <- await
        _ <- await
        _ <- await
        _ <- await
        _ <- await
        _ <- await
        _ <- await
        _ <- await
        _ <- await
        case v1 of
            Nothing -> return ()
            Just x -> do
              yield x >> loop

它确实有效,但我想知道这是否是最好的方法。

2 个答案:

答案 0 :(得分:7)

您可以使用replicateM_删除那些重复的await行。

v1 <- await
replicateM_ 11 await
case v1 of
   ...

答案 1 :(得分:2)

感谢Alec,Chad Gilbert和Michael Snoyman,我已经找到了以下解决方案:

get12th :: Monad m => Conduit Int m Int
get12th = loop
  where loop = do
          v <- await
          case v of
            Just x  -> yield x >> CL.drop 11 >> loop
            Nothing -> return ()

此解决方案使用drop函数来摆脱重复等待。在等待其他值之前,它会在收到第一个值后立即生成第一个值。