我遇到多个keys
可以指向完全相同的value
的情况。由于key
域非常小,我使用的是关联列表[(key, value)]
。
插入多个具有不同keys
但等于values
的元素会以任何方式强制GHC来创建相关values
的副本吗?
考虑到Haskell变量的不变性,我不这么认为,但我只想确定。
答案 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,但它不会有意义。