2011-12-29 40 views
9

免責事項:これは最近haskell-cafeリストで尋ねられました。誰かに私の謝罪は、ダブル投稿に悩まさ。列挙型の列挙型の作成

I(例えばiterateeiterIO、及びconduit)を知っているiteratee-実装パッケージのすべては、enumeratorパッケージを除き、enumeratee組成関数を定義します。これは重大な制限のように私には思える、そしてまだまた、実装が比較的簡単なようだ:

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の列挙型構成を定義しない別の理由はありますか?

+0

私は、この質問に彼をリンクさせる[列挙子パッケージ](http://hackage.haskell.org/package/enumerator)の著者/保守担当者、John Millikinにメールを送りました。 –

答えて

2

enumeratorの新しいリリース(0.4.17)には、(=$=)の演算子と上記の署名が含まれています。パッケージの作者に電子メールで送ったところ、パッケージには簡略化された多数の演算子(($=)(=$)、今は(=$=)など)を含めることに反対する良いケースがあります。

基本的に、問題は残された入力を処理することです。インナーIterateeによって得られただStream a'オーバー左joinIコンビネータ

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

破棄。 1は左オーバーデータのみが計算の終了時に破棄され

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

のようなスタイルを使用する場合、これは問題ではありません。ただし、単純化された演算子を使用すると複数の暗黙的な結合が行われ、残っているデータを追跡するのがずっと難しくなります。使用されている反復子が単純な場合(すなわち、残されたデータを生成しない場合)、これは問題ではなく、単純化された演算子は使用するのが理にかなっている。