4

重複の可能性:
Node.js に対する Haskell の応答は?
Haskellで複数のファイル/ソケットが読み取り/書き込み可能になるのを監視するにはどうすればよいですか?

nodejsのようにブロックしない方法でIOを実行するHaskellプログラムを書くことは可能ですか?

たとえば、遠く離れたデータベースから 10 件のレコードを取得したいので、10 件のリクエストを同時に発行し、結果が得られたら、このコレクションを返します。IO モナドは役に立ちません。なぜなら、モナドは明示的に bind で計算をシリアライズするからです。次に必要な計算を渡す継続渡しスタイルにも同じ問題があると思います。これも計算をシリアル化します。スレッドで作業したくないので、別の解決策を探しています。これは可能ですか?

4

2 に答える 2

20

Haskellスレッドは非常に軽量です。さらに、GHCのIOモナドは、多くの場合、イベント駆動型スケジューリングを使用します。つまり、通常のHaskellコードは、継続渡しスタイルのnode.jsコードのようなものです(ネイティブコードにコンパイルされ、複数のCPUで実行されるだけです...)

あなたの例は些細なことです

import Control.Concurrent.Async

--given a list of requests
requests :: [IO Foo]

--you can run them concurrently
getRequests :: IO [Foo]
getRequests = mapConcurrently id requests

Control.Concurrent.Asyncおそらく、先物のライブラリに関してあなたが探しているものとまったく同じです。Haskellは、ほんの数千の(通常の)スレッドを窒息させてはなりません。何百万ものIOスレッドを使用するコードを作成したことはありませんが、問題はメモリに関連するものだけだと思います。

于 2012-12-11T01:09:39.583 に答える
8

のコメントを具体化するために、パッケージControl.Concurrent.Asyncを使用した例を次に示します。async

import Network.HTTP.Conduit
import Control.Concurrent.Async

main = do
    xs <- mapM (async . simpleHttp) [ "www.stackoverflow.com"
                                    , "www.lwn.net"
                                    , "www.reddit.com/r/linux_gaming"]
    [so,lwn,lg] <- mapM wait xs
    -- parse these how ever you'd like

したがって、上記では、3 つの異なる Web サイトに対して 3 つの HTTP get 要求を定義し、それらの要求を非同期で起動し、3 つすべてが完了するのを待ってから続行します。

于 2012-12-11T04:24:09.253 に答える