これまでパイプを使用したことはありませんでしたが、チュートリアルを実行した後、非常に簡単であることがわかりました。
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
、モナドをパイプのベースモナドとして使用することもできます。
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"