【问题标题】:Why is there no built-in Set data type in Haskell?为什么 Haskell 中没有内置的 Set 数据类型?
【发布时间】:2011-09-26 14:22:35
【问题描述】:

有没有人可以向我解释为什么 Haskell 中没有定义 Set 数据类型?

旁注: 我只是在学习 Haskell 作为逻辑课程的一部分,其中集合论非常重要,因此在 Haskell 中拥有集合的概念非常方便。拥有一个列表并删除重复项(可能还有排序)也会产生一个集合,但我很好奇它是否没有内置的特定原因?

【问题讨论】:

  • 版主备注 此问题下的评论大多是噪音,或对噪音的反应,已被删除。请保持 cmets 具有建设性和主题性。
  • 我看到答案/cmets 建议使用列表。列表不是集合的有效替代品。在无序列表中查找元素的时间随着列表的大小而增长,在一个集合中,预计是恒定的。

标签: haskell types set


【解决方案1】:

正如其他答案所示,“为什么 Haskell 中没有 Set 数据类型?”被误导了:there is a Set data type

如果您想知道为什么 Set 不是 Haskell 的“内置”,您可能会问两件事之一。

要回答前者,这是因为该语言足够强大,可以表达集合的概念,而无需将其融入其中。作为一种高度重视函数式编程的语言,元组和列表的特殊语法是内置的, 但即使是像 Bool 这样的简单数据类型也在 Prelude 中定义。

为了回答后者,好吧,再次强调函数式编程,大多数 Haskeller 倾向于使用列表。 list monad 表示非确定性选择,通过允许重复,您可以在一定程度上表示加权选择。

注意how similar list comprehension syntax is to set notation。如有必要,您始终可以使用Set.fromList 将列表转换为“真实”集合。作为对 Barry 的不情愿的喊叫,这类似于使用 Python 的 set() 方法; Python 也有列表推导。

【讨论】:

  • 技术上,Data.Set 在 GHC 中,但不在 Haskell 98 或 2010 报告中
  • @user102008 “在 GHC 中”?它在containers package 中,包含在Haskell Platform 中,但我不确定你所说的“在 GHC 中”是什么意思。
  • @DanBurton 好吧,containers随 GHC 一起提供,即使你没有得到平台。
【解决方案2】:

在更哲学的层面上 --- 集合的数学概念和 Haskell 集合实现之间永远不可能有严格的对应关系。为什么不?好吧,首先是类型系统。一个数学集合可以包含任何东西:{x | x is a positive integer, i < 15} 是一个集合,但{1, tree, ham sandwich} 也是。在 Haskell 中,Set a 需要保存一些特定的类型。将 Doubles 和 Floats 放在同一个集合中不会进行类型检查。

正如其他人所说,如果您需要做一些类似集合的事情并且不介意类型限制,Data.Set 存在。它不在 Prelude 中,因为列表通常更实用。但实际上,从语言设计的角度来看,将数学集视为众多数据类型中的一种是没有意义的。集合比这更基本。你没有集合、数字和列表;你有一组数字和一组列表。递归类型的力量往往会掩盖这种区别,但它仍然是真实的。

不过,在 Haskell 中有一个地方,我们可以定义任意集合,然后在这些集合上定义函数。与 Haskell 中集合的数学概念最接近的类似物是类型系统本身。

【讨论】:

  • 很多时候,数学中的集合是在“宇宙”的背景下考虑的 (en.wikipedia.org/wiki/Universe_(mathematics))
  • @Zopa:你仍然可以使用 sum 类型来表达。
  • 确实,正如您所说,“在 Haskell 中,Set a 需要保存某种特定类型”。但是a 被实例化的类型可能是存在类型,其中1treeham sandwich 很可能是成员,假设treeham sandwich 本身就是类型良好的术语。 .. 你可以用这样一个集合做什么有意义的事我不知道;)但是我同意你的结论,类型本身是 Haskell 最接近集合的数学概念的东西。跨度>
  • A Set 还要求元素是 Ord 类的一部分(单例集除外)。
  • 正如@u0b34a0f6ae 指出的那样,更大的问题是集合需要Ord(Hashable, Eq) 约束,这使得集合在函数式编程中不如列表优雅(因为它不再是@987654336 @ 或 Monad)。
【解决方案3】:

它以Data.Set 存在。但是,正如您所说,它可以在 list 之上实现,因此构建语言不是必要,我认为这就是为什么它在模块中而不是作为一部分的原因语言本身的定义。

【讨论】:

  • @DietrichEpp 是的,但是如果您将写入列表添加为显式的 Cons 链,语法会非常繁重。
  • @mb14 (:) == Cons;只有显式有限列表的语法糖和各种enum{From}{Then}{To} 函数的包装器。
猜你喜欢
  • 2016-04-16
  • 2014-12-25
  • 2011-01-11
  • 2012-09-14
  • 1970-01-01
  • 2011-02-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多