为什么F#Set需要IComparable?

时间:2015-02-09 22:08:26

标签: f#

所以我试图将F#Set用作哈希表。但我的元素类型并没有实现IComparable接口(尽管它实现了IEquatable)。我得到一个错误,说因为比较约束而不允许构造。通过进一步阅读,我发现F#Set是使用二叉树实现的,这使得插入导致O(log(n))。这对我来说很奇怪,为什么Set结构是这样设计的?

编辑:所以我了解到F#中的Set实际上是SortedSet。我想这个问题变成了,为什么Sorted Set比一般Hash Set更适合作为不可变/功能数据结构呢?

1 个答案:

答案 0 :(得分:10)

有两个要点可以帮助您了解F#中的集合(以及一般的函数式语言)如何工作以及如何使用它们:

  • 实现不可变的哈希表(如.NET HashSet)很难 - 当你删除或添加元素时,你想避免复制数据结构中的所有内容(据我所知),没有一般的做法(你最终会复制太多,所以效率低下)。

    出于这个原因,大多数功能集被实现为(某种形式的树)。那些需要比较来构建一个排序树。平衡树的优点在于删除和添加元素不必复制树中的所有内容,因此即使是最坏的情况也是合理有效的(尽管可变哈希表仍然更快)。

  • 现在,F#是功能优先的,这意味着不可变结构是首选,但使用可变数据结构是完全正确的(特别是如果您将使用限制在一些定义明确且受限制的范围内)。出于这个原因,F#程序员经常使用DictionaryHashSet,尤其是当它只在单个函数的范围内时。