10

私はenumeratorライブラリに頭を悩ませようとしていますが、既存の2つの列挙型に関して新しい列挙型を構築したい状況に遭遇しました。私が列挙型を持っているとしましょう:

e1 :: Enumeratee x y m b
e2 :: Enumeratee y z m b

それらを組み合わせて1つの列挙型にできるはずだと感じています

e3 :: Enumeratee x z m b

しかし、パッケージでこれを行う既存の関数が見つかりませんでした。私はそのような関数を自分で作成しようとしましたが、反復の理解はまだ非常に限られているため、すべての複雑な型を一致させる方法を見つけることができませんでした.

基本的なコンビネータを見逃したのですか、それとも列挙型は互いに構成可能であるはずですか?

4

2 に答える 2

3

理論的には構成可能ですが、型は少し扱いに​​くいです。問題は、最初の enumeratee の最終パラメータbが実際には ではないことbです。それは別の iteratee です! 列挙型を構成するiteratee><>からの演算子の型は次のとおりです。

Prelude Data.Iteratee> :t (><>)
(><>)
  :: (Monad m, Nullable s1) =>
     (forall x. Enumeratee s1 s2 m x)
     -> Enumeratee s2 s3 m a -> Enumeratee s1 s3 m a

forall最初の enumerateeの余分に注意してください。これは、Rank-2 タイプが機能していることを示します。enumerator作成者が H98 互換性を維持したい場合(これが当初の目標の 1 つであったと思います)、このアプローチは利用できません。

ランク 2 の型を必要としない形式でこの型シグネチャを記述することは可能ですが、より長いか、構成されているのが実際には 2 つの列挙型であることが型から明確でないか、またはその両方です。たとえば、これは に対する ghc の推論された型です(><>):

Prelude Data.Iteratee> :t (><>>)
(><>>)
  :: (Monad m, Nullable s) =>
     (b -> Iteratee s m (Iteratee s' m a1))
     -> (a -> b) -> a -> Iteratee s m a1

これらの型はiterateeコンビネータ用ですが、うまくいけば、それらを適用できる十分な情報ですenumerator

于 2011-10-05T18:16:47.393 に答える
1

私は少し前にこの問題に遭遇しました。列挙型の構成を作成するには、最初に Iteratee (または Enumerator) が必要です。

これを行うことで開始できます:

モジュールのメイン
import Data.Enumerator
修飾された Data.Enumerator.List を EL としてインポート

メイン :: IO ()
main = run_ (enum $$ EL.consume) >>= 印刷
  どこ
    enum = (enumList 5 [1..] $= EL.isolate 100) $= EL.filter ペア
    ペア = (==0) . (`mod` 2)

前のコードは、enumeratee のリストを一緒に構成して新しい列挙子を作成し、consume Iteratee に適用されます。

($=) はEnumerator と Enumeratee を構成して新しい enumerator を作成するのに役立ちますが、(=$) はEnumeratee で Iteratee を構成して新しい Iteratee を作成するために使用できます。(=$) を使用して列挙型のリストを作成するときに型がボールを破壊しないことを考えると、後者をお勧めします。

モジュールのメイン
import Data.Enumerator
修飾された Data.Enumerator.List を EL としてインポート

メイン :: IO ()
main = run_ (enumList 5 [1..] $$ it) >>= 印刷
  どこ
    it = フォルダ (=$)
               EL.消費
               [ EL.isolate 100
               , EL.filter ((==0) . (`mod` 2))
               ]

Iteratee の代わりに Enumerator を作成して上記と同じ関数を実装しようとすると、 を使用すると無限再帰型エラーが発生しfoldl' ($=) (enumList 5 [1..]) [list-of-enumeratees]ます。

お役に立てれば。

于 2011-10-05T18:14:44.020 に答える