免責事項: 私は iteratee についてあまり知らず、一度も使用したことがありません。ですから、私の答えを一粒の塩で受け取ってください。
この定義は、Oleg のもの (より正確には、CPS スタイルの合計) と同等ですが、ひねりがあります: iteratee にアクセスすると、常にモナド値が返されることが保証されます。
オレグの定義は次のとおりです。
data Iteratee el m a =
| IE_done a
| IE_cont (Maybe ErrMsg)
(Stream el -> m (Iteratee el m a, Stream el))
done a
したがって、これは 、結果として与えa
られたもの、またはcont (Maybe ErrMsg) (Stream el -> ...)
: 入力の別のチャンクと、場合によってはエラーが発生した場合に反復を継続する方法 (この場合、継続を継続することは計算を再開することになります)の合計です。
Either a b
と同等であることはよく知られています: あなたにいずれかforall r. (a ->
r) -> (b -> r) -> r
を与えること、またはあなたが思いつく可能性のある変換の結果に対して、私はそのようなものを生成できることを約束することと同等です(そうするには、私が持っている必要があります) aまたは a )。ある意味では、 (Either ab)
はデータを導入し、このデータを削除
します。そのような関数が と名付けられた場合、はsomeのパターン マッチングと同等です。a
b
r
a
b
r
a
b
r. (a -> r) -> (b -> r) -> r
case_ab
case_ab (\a ->
foo_a) (\b -> foo_b)
case
ab of { Left a -> foo_a; Right b -> foo_b }
ab :: Either a b
したがって、ここに継続があります(ここで継続について話すのは
、「(a -> r)
それが であることがわかったら、その値がどうなるか」を表すためa
です)、オレグの定義と同等です:
data Iteratee el m a =
forall r.
(a -> r) ->
((Maybe ErrMsg), (Stream el -> m (Iteratee el m a, Stream el)) -> r) ->
r
しかし、 iteratee の定義にはひねりがあります (無害なカリー化を法とする): 結果はそうではありませんr
:m r
ある意味では、 iteratee のパターンマッチングの結果を常に monad に強制します
m
。
data Iteratee el m a =
forall r.
(a -> m r) ->
(Maybe ErrMsg -> (Stream el -> m (Iteratee el m a, Stream el)) -> m r) ->
m r
最後に、Oleg の定義の「反復の継続」データはStream .. -> m (Iterate .., Stream ..)
であるのに対し、 iteratee パッケージでは のみであることに注意してくださいStream -> Iteratee
。ここでモナドを削除したのは、外側のレベルでそれを強制しているためだと思います (反復を適用すると、モナドに住むことを余儀なくされるので、後続の計算もモナドに住むことを強制するのはなぜですか?)。出力がもうない理由はわかりません。Stream
これは、それらの Iteratee が利用可能なときにすべての入力を消費する必要があることを意味していると思います (または、戻り値の型で「まだ終了していない」ロジックをエンコードしますa
)。おそらく、これは効率上の理由によるものです。