Haskell 可变向量没有映射、折叠等......更高级别的功能?

Haskell mutable vectors have no map, fold, etc ... higher level functions?

提问人:rityzmon 提问时间:6/23/2016 更新时间:6/23/2016 访问量:387

问:

在第一次使用可变向量时,我发现虽然具有您期望的所有高级函数,例如 、 等,但可变版本没有这些函数。尝试在可变向量上使用不可变包中的函数不起作用。Data.Vector.UnboxedmapfoldData.Vector.Unboxed.Mutable

可变向量包缺少很多这些高级函数的原因是什么?

哈斯克尔 向量 可变

评论

1赞 Cactus 6/23/2016
如果你把它写成 和 的组合,它不会正确融合吗?foldfreeze
0赞 rityzmon 6/24/2016
@Cactus我不知道。没有这方面的文档。

答:

3赞 amalloy 6/23/2016 #1

我不知道这些类型的设计者在实现可变版本时的想法是什么,但我看到的问题与懒惰和对一致性的期望有关。

假设我创建了一个包含三个整数的可变向量,映射到它们上,然后修改原始向量。当我查看地图的输出时,我会看到旧值的双倍还是新值的双倍?答案是,这取决于我在修改之前查看了哪些元素,以及之后查看了哪些元素。考虑:(* 2)

main = do
  v <- V.replicate 3 1
  let doubled = map (* 2) v
  putStrLn "First doubled number is: " ++ show (head doubled)
  set v 10
  putStrLn "Sum of doubled numbers is: " ++ show (sum doubled)

虽然我们在定义明确的块中执行了我们的操作,但 thunks 的缓存意味着 的第一个元素 will 是 2,因为在我们将整个向量设置为 10 之前,我们必须强制它才能打印它,但 的最后两个元素将是 20,所以我们的总和是 42:既不是原始向量的两倍之和, 也不是最终向量的两倍之和。我们设法观察到一个不一致的状态,我们的系统作为一个整体从未打算处于这种状态,因为我们试图将一个可变向量视为一个不可变的列表,试图懒洋洋地覆盖它。doubleddoubledmap

评论

0赞 leftaroundabout 6/23/2016
这在多大程度上适用于严格的地图?
0赞 amalloy 6/24/2016
@leftaroundabout我不确定,因为值本身仍然很懒惰。例如,假设我映射的函数是 。即使在严格的地图中也会有同样的问题吗?我对 haskell 的砰砰声如何说得还不够熟悉。\x -> "Doubled number: " ++ (x * 2)
0赞 amalloy 6/24/2016
也许如果它既严格又严格,强制每个值都为 WHNF,它就会起作用。
3赞 Reid Barton 6/24/2016
这基本上解释了为什么 和 对于可变向量必须是(或)操作,因为它们需要读取向量的当前内容。矢量库没有这些吗?mapfoldIOST
0赞 rityzmon 6/24/2016
矢量库没有这些。