此代码试图热切地评估导致无限循环的[1..]
。
import qualified Data.Vector as V
infiniteLoop = V.zipWith (+) (V.fromList [1..4]) (V.fromList [1..])
为什么会这样?
答案 0 :(得分:8)
使用-O2
进行编译。
......好吧这只适用于某些情况。
在unoptimised
版本中,首先构建通过fromList
创建的两个向量。由于向量是脊椎严格的(并且是未装箱的超限),因此无法构造无限大小的向量,因此会失败。
如果使用-O2
进行编译,stream fusion
就会发挥作用。现在,根本不创建所有中间向量(来自fromList
的向量)。由于zipWith
在第一次提供数据后停止,因此您现在具有终止功能。
但总的来说:不要将无限大小的耗材与向量运算一起使用,函数的语义现在取决于你的优化级别,这很糟糕。
原始"stream fusion" paper描述了从列表到流的切换,再次回到列表。为简化起见,您可以将列表视为向量(因为向量会添加一些额外的内容,如内存分配,monadic行为等)。
通常(并且简化得很多),重写规则用于在内部将矢量表示为流,启用融合,然后将流转换回矢量。
答案 1 :(得分:5)
Data.Vector.fromList为documented需要O(N)时间。在这里,您提供了无限数量的项目,因此需要无限的时间才能完成。
为什么不能懒惰地构造向量:它们对其他操作(获取,删除,长度,索引......)保证良好的性能,这需要使用知道存在多少元素的数据结构。 / p>