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

Keep every nth element of a conduit stream

我正在使用 Conduit 以类似流的方式解析一些数据。在流中的某个时刻,我需要每 12 个元素。有什么方便的方法吗?

我目前正在明确等待 12 个元素,只是 return 第一个元素:

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

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

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

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

感谢 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 函数来消除重复等待。在等待其他值之前,它会在收到第一个值后立即产生第一个值。