Haskell"复制构造函数"调用

时间:2016-04-08 04:43:29

标签: haskell

我遇到多个keys可以指向完全相同的value的情况。由于key域非常小,我使用的是关联列表[(key, value)]

插入多个具有不同keys但等于values的元素会以任何方式强制GHC来创建相关values的副本吗?

考虑到Haskell变量的不变性,我不这么认为,但我只想确定。

2 个答案:

答案 0 :(得分:2)

从技术上讲,它取决于Haskell的实现:Haskell报告并未强制要求制作副本,或者要避免,它只是要求结果是正确的 - 除了性能问题。

话虽如此,你不应指望GHC优化这个

let value1 = "hello" ++ "world"
    value2 = "hell" ++ "oworld"
in [(1, value1), (2, value2)]

进入这个

let value = "helloworld"
in [(1, value), (2, value)]

仅仅因为两个值相等,并不意味着它们将共享相同的内存区域。

在后一个示例中,当将两次放入列表时,不会复制字符串value,因为不需要:将使用指向同一字符串的字段构造两对。因此,只会复制指针。

保存副本也是有时我们不写

的原因
foo (x, "hello") = (x, "hello")
foo (x, y)       = (x, "foo:" ++ y)

但更喜欢

foo p@(x, "hello") = p
foo (x, y)         = (x, "foo:" ++ y)

后者将输出相同的“指针”到输入对,而不是构造具有相同值的新指针。 (我不确定GHC是否有时会自行进行优化)

答案 1 :(得分:1)

你是对的,

但令人信服的一点可能不是可变性而是懒惰。实际上,如果你要“复制”这个值,那么它“将有”被评估[1]。但这会打破哈克尔的懒惰。

另外,关于“大小”的推理在Haskell中可能很奇怪:foldr (+) [1..1000]的大小是Int吗?还是函数闭包的大小?

1)从严格来说,你可以想象复制thunk,但它不会有意义。