我以前没有使用过 Pipes,但是在阅读完教程后,我发现它非常简单:
import Pipes
import qualified Pipes.Prelude as P
nums :: Producer Int IO ()
nums = each [1..20]
process :: Producer Int IO ()
process = nums >-> (P.drop 5) >-> (P.take 5)
result :: IO Int
result = P.fold (+) 0 id process
main = result >>= print
更新:
由于示例中没有“有效”的处理,我们甚至可以使用Identity
monad 作为管道的基本 monad:
import Pipes
import qualified Pipes.Prelude as P
import Control.Monad.Identity
nums :: Producer Int Identity ()
nums = each [1..20]
process :: Producer Int Identity ()
process = nums >-> (P.drop 5) >-> (P.take 5)
result :: Identity Int
result = P.fold (+) 0 id process
main = print $ runIdentity result
更新 1:
下面是我想出的解决方案(对于要点链接评论),但我觉得它可以变得更优雅
fun :: Pipe Int (Int, Int) Identity ()
fun = do
replicateM_ 5 await
a <- replicateM 5 await
replicateM_ 5 await
b <- replicateM 5 await
yield (sum a, sum b)
main = f $ runIdentity $ P.head $ nums >-> fun where
f (Just (a,b)) = print (a,b)
f Nothing = print "Not enough data"