gpt4 book ai didi

haskell - 如何在 Haskell 中产生并发计算?

转载 作者:行者123 更新时间:2023-12-01 12:26:59 26 4
gpt4 key购买 nike

如果我有一个函数执行四次非常长的计算并返回一个包含四次计算结果的列表,但每个计算不依赖于另一个,你如何在 Haskell 中“并行化”它?

为了更好地解释我的问题,这里有一个 Clojure 示例来说明我的想法:

(defn some-function [arg1 arg2 arg3 arg4]
let [c1 (very-long-computation arg1)
c2 (very-long-computation arg2)
c3 (very-long-computation arg3)
c4 (very-long-computation arg4)]
[c1 c2 c3 c4])

你可以产生三个额外的线程来做,比如说:

(defn some-function [arg1 arg2 arg3 arg4]
let [c1 (future (very-long-computation arg1))
c2 (future (very-long-computation arg2))
c3 (future (very-long-computation arg3))
c4 (very-long-computation arg4)] ; no need to wrap c4 in a future
[@c1 @c2 @c3 c4])

Haskell 中的类似内容是否等效?

someFunction :: (a -> a -> a ->a) -> [a]
do c1 <- rpar (very-long-computation arg1)
c2 <- rpar (very-long-computation arg2)
c3 <- rpar (very-long-computation arg3)
c4 <- (very-long-computation arg4)
rseq c1
rseq c2
rseq c3
return (c1, c2, c3, c4)

我需要 rpar/rseq c4 吗?

rpar/rseq 是进行此类并发计算的方法吗?

如果我不使用 rseq,程序会在稍后尝试访问返回列表中的返回值时等待吗?

这是透明的还是您需要做类似 Clojure 中使用“@”时发生的“deref”之类的事情?

最佳答案

您很可能正在寻找 async包裹。例如,如果您想对这三个计算进行竞赛并选择最先完成的计算:

someFunction :: IO a
someFunction = do
c1 <- async $ veryLongComputation1
c2 <- async $ veryLongComputation2
c3 <- async $ veryLongComputation3
(_, a) <- waitAny $ [c1, c2, c3]
return a

或者您可以在特定的async 线程上使用wait,并通过stm 共享状态。对于这类事情,这是一个非常有用的包。您在 OP 中要求的精​​确版本如下所示:

someFunction :: IO (a, b, c, d)
someFunction = do
c1 <- async $ veryLongComputation1
c2 <- async $ veryLongComputation2
c3 <- async $ veryLongComputation3
v4 <- veryLongComputation4
-- wait for all the results and return them as a tuple
wait $ (,,,) <$> c1 <*> c2 <*> c3 <*> (return v4)

这当然假设 c1, c2, c3 都是副作用,您对结果不感兴趣。 waitpoll 获取值。

我还强烈推荐 Simon Marlow 的《Haskell 中的并行和并发编程》一书。

关于haskell - 如何在 Haskell 中产生并发计算?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23353898/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com