1

这段代码如何:

parfib :: Int -> Int
parfib 0 = 1
parfib 1 = 1
parfib n = nf2 `par` (nf1 `par` (nf1+nf2+1))
           where nf1 = parfib (n-1)
                 nf2 = parfib (n-2)

比这更好:

parfib :: Int -> Int
parfib 0 = 1
parfib 1 = 1
parfib n = nf2 `par` (nf1 `seq` (nf1+nf2+1))
           where nf1 = parfib (n-1)
                 nf2 = parfib (n-2)

我没有得到我在网上找到的解释说“为了保证以正确的顺序评估主表达式(即不阻塞子任务上的主任务),使用了 seq 注释”。

为什么要使用 seq?我知道它强制解释器首先评估 parfib (n-1) 但为什么有必要?

在执行第二个程序时,interpeter 不会触发一个新进程来评估 nf2,同时并行评估 nf1+nf2+1 表达式的 nf1 吗?有什么需要告诉它指定它应该以 nf1 开头?

4

2 回答 2

4

nf1并行评估没有多大意义,nf1+...因为后者取决于 nf1,所以它所做的只是阻止nf1. 使用seq它只会在nf1您知道它已被评估后尝试使用。

于 2009-04-03T10:54:40.580 回答
0

这可能是因为我们希望根据我的理解最小化火花的数量,这两个版本会产生相同的结果

但是使用第一个选项,您将触发两个额外的进程(nf1,nf2)。但是当我们使用 seq 时,我们只会触发一个附加进程(nf1)。

于 2009-06-06T20:46:10.217 回答