13

パイプは iteratee の本当にエレガントでシンプルなバージョンです。awaitプリミティブとを使用して、パイプ コードを非常に簡単に記述できますyield。Paolo Capriotti は、保護されたパイプtryAwaitを使用してパイプの概念を拡張しました。これは、入力フローがなくなると、パイプが何らかのファイナライズを実行できるようにする、もう少し複雑なプリミティブを使用します。

保護されたパイプの実装は、次awaitの点で再定義されますtryAwait

await = tryAwait >>= maybe discard return

私の質問は次のとおりです。単純な Pipes 実装 ( awaitandを使用yield)を対象としたコードを記述した場合、同じコードを使用して、保護されたパイプ実装に切り替えると同じように動作しますか? 言い換えれば、保護されたパイプ コードは、動作の観点から、単にパイプ コードのスーパーセットとして扱うことができますか?

4

2 に答える 2

11

Pipesを投稿したGabrielです。私は Paolo と協力しており、彼の最初の提案よりもさらに強力でタイプセーフな、より洗練された実装を開発中です。あなたの質問に対する簡単な答えは、最終的な実装は元のパイプのスーパーセットであり、同じ動作とセマンティクスで以前と同じコードを書くことができるということです。

ここでもかなり簡単に要約できます。await ステートメントと yield ステートメントは、パイプが制御を放棄できる唯一の方法であるため、上流または下流のパイプが終了した場合にフォールバックをそれぞれにアタッチします。フォールバックはパイプを永久にダウングレードし、失敗したアクションを繰り返すことはできなくなります。await が失敗するとパイプがプロデューサーにダウングレードされ、yield が失敗するとパイプがコンシューマーにダウングレードされます。生産者が生成に失敗した場合、または消費者が待機に失敗した場合、それらは基本モナドに格下げされ、もはや失敗することはありません。

コンシューマーとプロデューサーは別のタイプになり、公開されなくなりました。これらは、Await または Yield コンストラクターがないことを除いて、型パイプ型と同じです。await ステートメントを禁止できるパイプの入力型がないため、少なくともプロデューサー型ではこれが必要です。

await ステートメントと yield ステートメントは、フォールバック動作としてデフォルトで終了します。これは以前と同じ動作です。await と yield は、それらをサポートするダウングレード状態で動作するように型分類されます。ただし、tryAwait や tryYield よりも魅力的な名前が思いついたら、オプションで独自のフォールバックを提供できるようになりました。

パイプがこの拡張機能でカテゴリを形成していることをまだ確認する必要がありますが、その可能性は非常に高いようです。また、100% タイプセーフであり、型を使用して、ブール値ではなくダウングレードを強制し、プログラマーによって証明された不変式を使用します。

編集:あなたの食欲をそそるいくつかの機能するコード(拡張機能を使用するには、githubリポジトリから「try」ブランチをチェックアウトしてください):

printer = forever $ await >>= lift . print

take' n = replicateM_ n $ await >>= yield

fromList' = mapM_ (yieldOr (lift $ putStrLn "Undelivered elements))

diagnose = forever $ do
    x <- awaitOr (lift $ putStrLn "Await failed")
    yieldOr (lift $ putStrLn "Yield failed") x

> runPipe $ printer <+< take' 3 <+< diagnose <+< fromList [1..10]
1
2
3
Yield failed
Undelivered elements
> runPipe $ printer <+< take' 10 <+< diagnose <+< fromList [1..3]
1
2
3
Await failed
于 2012-02-05T01:45:22.390 に答える
5

答えはイエスです。

Hackage でのパイプの現在の実装では、待機中のパイプは上流が終了するとすぐに終了します。関数を使用する場合、保護されたパイプでも同じことが言えますawaittryAwait終了前に特別な動作が必要な場合は、代わりに使用するオプションがあります。

さらに、「保護されたパイプ」は、機能を統合するための最善の方法を模索している間、概念の一時的な名前にすぎません。別々にリリースされることはないと思います。

于 2012-02-05T01:44:50.487 に答える