2016-04-08 111 views
0

我有一個情況,其中多個keys可以指向完全相同的value。由於key域很小,我使用關聯列表[(key, value)]Haskell「複製構造函數」調用

是否插入多個不同的元素keys但等於values強制GHC以任何方式創建有關values的副本?

考慮到Haskell變量的不變性,我不這麼認爲,但我只是想確定一下。

+0

你能澄清你指的是什麼意思嗎?你有類似'a = 4; b = [(1,a),(2,a)]'? –

+0

是的,就像那樣:)我的擔心是,如果'a'變量很大(認爲是10兆字節),那麼拷貝它只會對士氣不利 –

+0

這可能有所幫助:http://stackoverflow.com/questions/20857165/move-or-copy-in-haskell-vs-c –

回答

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 [email protected](x, "hello") = p 
foo (x, y)   = (x, "foo:" ++ y) 

後者將輸出相同的「指針」,以輸入對,而不是構建原因一個具有相同價值的新產品。 (我不確定GHC是否有時自己做這種優化)

1

你是對的,

但令人信服的點可能不是imutability但懶惰。事實上,如果你要「複製」這個值,那麼它將「被評估」[1]。但這會打破哈斯克爾的懶惰。

另外,有關「大小」的推理可能在Haskell中出現問題:是foldr (+) [1..1000]大小爲Int?或者函數閉包的大小?


1)嚴格來說,你可以想象複製thunk,但它沒有任何意義。