Haskell 并行延迟计算

Haskell lazy evaluation in parallelism

如果值 x 在列表中,其中 x 是某个函数 parList 在该列表中被调用(例如 [l,x,l,x]x 计算一次还是两次?

根据我对 Haskell 惰性求值的理解,一旦 x 被求值,就不需要再次求值,因为它会 return 相同的值。但这适用于多线程环境吗?

每当您为计算创建 spark (这就是 parList 所做的)总有可能 该计算的工作将执行两次。 实际上,这种情况很少发生。基本上有一个竞争条件 在处理火花的线程和主线程之间。

Haskell 通过初始设置变量的值来实现惰性 到 thunk - 本质上是指向计算值的代码的指针。 当要求变量的值时,Haskell 运行s 指向的代码 to by the thunk 并用返回值替换thunk。 如果稍后使用该变量,Haskell 只使用存储的值。

当您并行评估一个变量时,会创建一个 spark 指向 变量。当火花由后台线程处理时 只需要 spark 指向的值。如果火花点 对于 thunk,thunk 是 运行 并用返回值更新。 如果火花指向已评估的值,则什么也不会发生 我们说火花 fizzles.

因此,如果您并行计算 [x,x,x,x,x,x] 这样的列表,一个火花 将为列表的每个元素创建,并且有可能 这些火花中的两个或多个将同时执行。也是 主线程可能会同时评估 x 。 在这种情况下,计算 x 的工作将被重复。 但是,一旦更新了 x 的 thunk,就没有 spark 或主线程 之后开始计算 x 将重新计算 x.