2015-10-13 82 views
1

爲什麼把小寫字母爲Set當差?差異,當把小寫字母爲集

哈斯克爾

λ: import Data.Set as S 
λ: Prelude.foldr (\e acc -> S.insert e acc) S.empty ['a' .. 'z'] 
fromList "abcdefghijklmnopqrstuvwxyz" 

斯卡拉斯卡拉的

scala> ('a' to 'z').toList.toSet 
res5: scala.collection.immutable.Set[Char] = Set(e, s, x, n, j, y, t,    
    u, f, a, m, i, v, q, b, g, l, p, c, h, r, w, k, o, z, d) 

回答

8

默認設置實施是一個哈希集合,所以也沒有下令。 Haskell中的默認集合實現是一個有序集合,它是有序的。 (您需要一個Ord實例來插入一個新元素:insert :: Ord a => a -> Set a -> Set a

要在Scala中維持秩序,你將不得不使用一個SortedSet的,就像這樣:

scala> import scala.collection.immutable._ 
scala> ('a' to 'z').to[SortedSet] 
res4: scala.collection.immutable.SortedSet[Char] = TreeSet(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z) 

下面是一些有關的背景不同的選擇:

Scala選擇基於哈希的實現,因爲這在JVM世界中很常見,並且因爲哈希表通常比排序的集合快得多。其缺點是哈希代碼引入了一些非確定性,特別是與使用默認哈希代碼實現的類相結合時。

Haskell將純度置於性能之上,因此它選擇了更確定的排序集合。

+0

你(都)是在談論*插入*順序還是*自然順序的元素? –

+0

@SillyFreak'TreeSet'按自然順序排列元素,而不是按插入順序排列。 – Jesper

+0

我知道,我的評論意在指出(現已刪除)評論中的含糊不清,以及對答案的較低程度。 –

2

Set只是一個名稱,描述了一個數據結構,它沒有排序並且不允許有重複的元素。其他一切基本上都取決於實現。

現在,您已經經歷了一組Haskell是有序的,即它的元素需要一個Ord實例,用於定義低於他們的關係。 Scala的默認實現Set特性似乎是HashSet,因此順序似乎是隨機的;實際上它反映了桶元素的順序。

在很多情況下,當一個集合是正確的數據結構時,排序並不重要(檢查成員資格,跟蹤不同對象的數量,...) 。如果是這樣,有Scala中專門選擇具有比Set性狀的嚴格的合同,這與Java一樣:SortedSet對於有邏輯順序,或者LinkedHashSet,它保留插入順序迭代元素,但使用哈希集合數據結構用於通常的設置操作。

+2

Haskell'Set'不保留插入順序;它按順序存儲集合的元素。它使用大小平衡的二叉樹實現。 – Cirdec

+0

謝謝,我不確定。我刪除了不相關的信息 –