これはさまざまな方法で行うことができますが、countEvents
とlogEvents
は両方ともストリーム上でフォールドされているため、outputFoldM
の繰り返し適用がおそらく最も簡単です。フォールドをリンクする方法ほどストリームを分割する方法を探しているわけではありません。 outputFoldM
は、繰り返しの折り畳み操作を適用した結果に関連付けられたストリームを新しいストリームに変換し、結果を「側に」書きます。何が価値があるために
>>> let logger = IOS.inputFoldM (\() x -> print x >> putStrLn "----")()
>>> let counter = IOS.inputFoldM (\a _ -> return $! a + 1) (0::Int)
>>> ls0 <- IOS.fromList [1..5::Int]
>>> (ls1,io_count) <- counter ls0
>>> (ls2,_) <- logger ls1
>>> IOS.fold (+) 0 ls2
1 -- here we see the "logging" happening from `logger`
----
2
----
3
----
4
----
5
----
15 -- this is the sum from the `fold (+) 0` that actually exhausted the stream
>>> io_count
5 -- this is the result of `counter`
、私はInputStreams
https://github.com/snapframework/io-streams/issues/53にfoldl
ライブラリからFold
sおよびFoldM
秒を適用することを可能にするためのパッチを書きました。これは、あなたが無限に多くの同時折り目を適用することを可能にします。これは同じ折り目/シンクがそのように適用されています。私はApplicativeDo
を使って "ロギング"を行い、統計情報を収集してフォーマットしました。同じことは、適用可能な演算子で書くことができます。彼らは、任意のフレームワークに特別ではありませんので、
{-#LANGUAGE ApplicativeDo #-}
import qualified System.IO.Streams as IOS
import qualified Control.Foldl as L
import Control.Lens (filtered)
main = do
ls <- IOS.fromList [1..5::Int]
res <- L.impurely IOS.foldM_ myfolds ls
putStrLn res
myfolds = do
sum_ <- L.generalize L.sum -- generalize makes an 'impure' fold
length_ <- L.generalize L.length -- out of a pure one like sum or length
odd_length_ <- L.generalize (L.handles (filtered odd) L.length)
_ <- L.sink (\n -> print n >> putStrLn "-------")
pure (format sum_ length_ odd_length_)
where
format sum_ length_ odd_length_ = unlines
[ ""
, "Results:"
, "sum: " ++ show sum_
, "length: " ++ show length_
, "number odd: " ++ show odd_length_]
だから、これは「美しい折りたたみは」foldl
中のもののように折るこの
>>> main
1
-------
2
-------
3
-------
4
-------
5
-------
Results:
sum: 15
length: 5
number odd: 3
のように見えるがいいです。 myfolds
を変更せずにリストに追加することができます。Sequence
、ボックス化されていないベクトル、パイプProducer
、コンジットSource
などです。これは、超コンポジットの折り目とシンクの別個の規律です。
あなたが参照している 'InputStream'がわかるように、インポートを含めるべきです。このタイプはいくつかの異なるモジュールが定義されています:[(リンク)](http://hayoo.fh-wedel.de/?query=InputStream) – ErikR
1つのオプションは、1つの入力から要素を受け取る個別のスレッドを作成することです['Chan'](https://hackage.haskell.org/package/base-4.8.1.0/docs/Control-Concurrent-Chan.html#t:Chan)、2つ(またはそれ以上)の出力チャンネルに送信します。そして、[System.IO.Streams.Concurrent](https://hackage.haskell.org/package/io-streams-1.3.5.0/docs/System-IO-Streams-Concurrent.html)を使ってそれらを適切にバインドします。 –