4

可能重复:
Haskell 对 Node.js 的响应是什么?
如何在 Haskell 中查看多个文件/套接字以使其可读/可写?

是否可以编写一个像 nodejs 那样以非阻塞方式执行 IO 的 Haskell 程序?

例如,我想从一个很远的数据库中获取 10 条记录,所以我想同时触发 10 个请求,当结果可用时,然后返回这个集合。IO monad 不会有帮助,因为 monad 使用 bind 显式地序列化计算。我认为你传递接下来想要的计算的延续传递风格有同样的问题,它再次序列化计算。我不想使用线程,我正在寻找另一种解决方案。这可能吗?

4

2 回答 2

20

Haskell 线程的重量非常轻。更重要的是,GHC 的 IO monad 大部分时间都使用事件驱动调度,这意味着普通的 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

因此,在上面我们为三个不同的网站定义了三个 HTTP get 请求,异步启动这些请求,并等待所有三个完成后再继续。

于 2012-12-11T04:24:09.253 回答