5

ProxyHaskell Pipesに 2 つあるとしましょう。これらは、外部システム プロセスを表します。

produce :: MonadIO m => Producer ByteString m ExitCode
consume :: MonadIO m => Consumer ByteString m ExitCode

したがってEffect、次のように、それらを にフックします。

effect :: Effect m ExitCode
effect = produce >-> consume

これにより、終了する最初からがEffect得られます。通常、これはではなく になります。最初に終了しない場合でも、パイプの戻り値を取得する慣用的な方法は何ですか?ExitCodeProxyproduceconsumeconsume

consumeこれまでのところ、ストリームが完了したことを認識できるように、ある種の厄介なインバンド シグナリングを行わなければ、これは不可能だと考えています。最後の Proxy がシャットダウンすることを知る唯一の方法は、 から何かを取得することです。そのため、ストリームが終了したことを知らせるawaitために空を送ることができます。ByteStringしかし、それは正しくありません。私が今持っているのは、終了値を提供できる別のMVarですが、これを行うにはもっと慣用的な方法が必要だと思います。

4

2 に答える 2

5

インバンド シグナリングがなければ、 が最初に戻っConsumerた場合に「戻り値」を取得することはできませんProducer。プロデューサーがreturningの場合Consumer、要求された値を待ってブロックする必要があることを意味します。が再度実行されることはないため、 が要求された値の帯域内信号を取得するまで、Consumerを実行する機会がありません。returnConsumer

シグナリングが帯域内であるからといって、それが「厄介」である必要があるというわけではありません。をキャプチャして下流に転送することにより、返される可能性のある aProducerを、返されないProducerことがわかっている (戻り値の型が である) に変換できます。別のリクエストが上流に戻ってきた場合に備えて、これを行います。forall r' . r'returnforever

returnDownstream :: Monad m => Proxy a' a b' b m r -> Proxy a' a b' (Either r b) m r'
returnDownstream = (forever . respond . Left =<<) . (respond . Right <\\)

最後Consumerに、値が ed のときに何をすべきかを明示的に処理する必要がありますがrequest、応答を取得する代わりに ( a でRight) 上流のプロデューサーの戻り値を取得します ( a でLeft)。

于 2015-03-27T21:50:57.890 に答える