の定義Enumerator
は次のとおりです。
type Enumerator a m b = Step a m b -> Iteratee a m b
ドキュメントには、s がデータを消費している間Iteratee
、s がデータをEnumerator
生成すると記載されています。このようなタイプのデータを生成する方法を理解できます。
enumStream :: (Monad m) => Stream a -> Enumerator a m b
enumStream stream step =
case step of
Continue k -> k stream
_ -> returnI step -- Note: 'stream' is discarded
(はこれよりも複雑です...が与えられた後に がそうでないenumEOF
ことを確認し、そうである場合はエラーをスローするようです。)Iteratee
Continue
EOF
つまり、で実行すると、 がIteratee
生成されます。これは列挙子に供給され、続行できるように列挙子に供給されます。私の列挙子は結果の継続を返します。Step
runIteratee
Step
Stream
Iteratee
1 つ気になる点があります。このコードはモナドで実行されています。つまり、データを消費できるということですよね?
-- | Like 'enumStream', but consume and discard a chunk from the input stream
-- simply because we can.
enumStreamWeird :: (Monad m) => Stream a -> Enumerator a m b
enumStreamWeird stream step = do
_ <- continue return -- Look, mommy, I'm consuming input!
case step of
Continue k -> k stream
_ -> returnI step
ドキュメントには、列挙子がソースとシンクの両方として機能する場合は、Enumeratee
代わりに使用する必要があると記載されています。
type Enumeratee ao ai m b = Step ai m b -> Iteratee ao m (Step ai m b)
しかし、明らかにそうする必要はありませんでした。Enumerator
関数で示されているように、 の定義で入力を使用できenumStreamWeird
ます。
私の質問は次のとおりです。
Enumerator
のように 内でデータを「消費」しようとするとどうなりますenumStreamWeird
か? データはどこから来たのですか?列挙子でデータを消費するほど狂っていなくても、生成しているデータを読み取る iteratee に代わってではなく、列挙子に代わって基礎となるモナドでアクションを実行することは有効ですか?
後者の質問は私の主な質問とはあまり関係がないかもしれませんが、 anEnumerator
がどのように機能するかを理解しようとしています。