9

免責事項: これは haskell-cafe リストで最近質問されたものです。二重投稿でお騒がせした方にはお詫び申し上げます。

私が知っているすべての iteratee 実装パッケージ (例: iterateeiterIO、およびconduit) は、パッケージを除いて、enumeratee 構成関数を定義しenumeratorます。これは深刻な制限のように思えますが、実装も比較的簡単に思えます。

import Data.Enumerator
import Data.Enumerator.Internal

(=$=) :: Monad m
      => Enumeratee a0 a1 m (Step a2 m b) -> Enumeratee a1 a2 m b
      -> Enumeratee a0 a2 m b
(=$=) e01 e12 step = Iteratee $ do
    step' <- runIteratee $ e12 step
    runIteratee . joinI $ e01 step'

私が見逃している落とし穴はありますか?enumeratorまたは、列挙型の構成を定義しない他の理由はありますか?

4

1 に答える 1

2

の新しいリリース (0.4.17) があり、上記の署名を持つオペレーターenumeratorが含まれています。(=$=)パッケージの作成者に電子メールを送信したところ、パッケージに多数の単純化された演算子 ( ($=)(=$)、および now など(=$=)) を含めることに対して、彼は良い主張をしています。

基本的に、問題は残りの入力を処理することです。joinIコンビネータ_

joinI :: Monad m => Iteratee a m (Step a' m b) -> Iteratee a m b

Stream a'inner によって生成された残りを破棄しIterateeます。次のようなスタイルを使用する場合、これは問題ではありません

joinI (foo $$ (bar $$ baz))

残りのデータは、計算の最後にのみ破棄されます。ただし、単純化された演算子を使用すると、複数の暗黙的な結合が発生し、残りのデータを追跡するのがはるかに難しくなります。使用されている iteratee が単純である (つまり、残りのデータを生成しない) 場合、これは問題ではなく、単純化された演算子を使用する意味があります。

于 2012-01-02T05:04:28.197 に答える