使用默认值管道`take`

pipes `take` with default value

我有一个类型为 Producer Message IO (Producer SB.ByteString IO ()) 的生产者 p。 现在我需要选择性地跳过一些消息并选择性地处理一定数量的消息:

       let p =
             (processMBFile f >->
              P.drop (optSkip opts)
              >->
              (case optLimit opts of
                 Nothing -> cat
                 Just n  -> ptake n)
             )
       in
         do
           restp <- runEffect $ for p processMessage

我无法使用 Pipes.Prelude 中的 take 因为它 return 是 () 而我需要 return 一个空的生产者。我快速破解它的方法是用我自己的实现 ptake:

替换 take
emptyP :: Producer SB.ByteString IO ()
emptyP = return ()

ptake :: Monad m => Int -> Pipe a a m (Producer SB.ByteString IO ())
ptake = go
  where
    go 0 = return emptyP
    go n = do
        a <- await
        yield a
        go (n-1)

我的问题是:是否有更优雅的方法来做到这一点?

ptaketake 的区别仅在于 return 值,因此可以使用 (<$):

来实现
ptake n = emptyP <$ take n