这段代码如何:
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),但为什么有必要呢?
当执行第二个程序时,不会引发一个新的过程来评估nf2,而并行评估nf1 + nf2 + 1表达式的nf1?有什么需要告诉它指定它应该以nf1开头?
答案 0 :(得分:4)
与nf1
并行评估nf1+...
没有多大意义,因为后者依赖于nf1,所以它所做的就是阻止nf1
的火花。使用seq
只有在您知道评估后才会尝试使用nf1
。
答案 1 :(得分:0)
可能是因为我们希望尽量减少火花的数量 从我的理解,两个vesrsion将产生相同的结果
但是第一个选项会激发两个额外的过程(nf1,nf2)。但是当我们使用seq时,我们只激发一个额外的过程(nf1)。