3

pipes-concurrency次のようなコードがあります。

-- this won't compile but will give you the gist of what's happening
pipeline :: MonadIO m => Consumer a m ()
main = do
    (output, input) <- spawn Unbounded
    async $ do runEffect $ fromInput input >-> pipeline
               performGC
    -- skipped the `output` pipeline code.

質問 1 : これは明らかにコンパイルされませrunEffectん。これを行う方法はありますか?それとも、パイプラインが IO モナド内にエフェクトを含めるように強制するのに行き詰まっていますか?MonadIO m => m ()asyncIO a

質問 2 : MonadIO を実装する Monad 内に async を埋め込むことは理にかなっていますか? ここで自分自身をうまく表現できているかどうかはわかりません。

ありがとうございました!

4

2 に答える 2

2

runEffect戻りMonadIO m => m ()、非同期が必要になるため、これは明らかにコンパイルされませんIO a

それは正しくありません。IO インスタンスであるMonadIOため、の出力をrunEffect渡すことができます。たとえば、 (インスタンスでもあります)async関数を取ることができます。MaybeT IO ()MonadIO

あなたが探しているのはでliftIO :: IO a -> m aあると思います.IO (Async a)asyncMonadIO

...
liftIO $ async $ do runEffect $ fromInput input >-> pipeline
           performGC

これをコンパイルしようとはしていません。IO関数の他の部分も持ち上げる必要があるかもしれません。

質問 2: MonadIO を実装する Monad 内に async を埋め込むことは理にかなっていますか? ここで自分自身をうまく表現できているかどうかはわかりません。

確かに、いくつかのモナド スタックで並行処理を実行したい場合は、なぜですか?

于 2014-06-06T22:00:16.887 に答える
0

私はまったく同じことをしようとしていますが、これが問題の核心です:

$ :t async . runEffect
async . runEffect :: Effect IO a -> IO (Async a)
$

一言で言えば、私はこの種のものを提供することが期待されています。しかし、私が本当に欲しいタイプは次のとおりです。

someAsync . runEffect :: MonadIO m => Effect m a -> m (Async a)

残念ながら、これを実現する方法がわかりません。現在、これは不可能に思えますが、パイプの同時実行性のためではなく、純粋に async の種類のためです。

両方のライブラリの開発者にこの質問をするように指示する必要があると思います。そうしないと、必要な型を取得する方法がわからないからです。

編集 1 : MonadIO サポートを async に追加したくないというこの問題を見つけました。

編集 2 : Pipes ライブラリが大好きですが、この問題の解決策を見つけるのに苦労しています。この問題に対する答えが見つからない場合は、Data.Conduit.Async からのバッファーを使用することがあります。これは、この問題をうまく解決しているように見えるからです。

編集 3 : この問題の正しい解決策は、Lifted-asyncを使用することです。このライブラリは、次のメソッドを提供します。

async :: MonadBaseControl IO m => m a -> m (Async (StM m a))

Monad に MonadBaseControl IO を実装している限り、それはまさにあなたが求めていることを行うはずです。

于 2015-02-11T22:18:46.070 に答える