我正在将一些Haskell代码从使用列表更改为集合。我想我了解所有必需的内容,但是我不确定如何在集合上进行模式匹配。列表具有很好的文字语法,似乎很难用Set构造函数来模仿。例如,我可能有一些这样的代码:

foo [] = []
foo x = other_thing

如何编写此代码,使其使用集合而不是列表?

最佳答案

好吧,你不能。
Set是一种抽象的数据类型[0],有意隐藏其内部表示形式,主要是为了维护类型系统无法静态强制执行的数据结构的不变性(特别是标准库Data.Set.Set是二进制搜索树)。

失去对抽象数据类型进行模式匹配的功能会带来一些令人不愉快的附带损害,但是很好。您的选择大致是:

  • 使用布尔谓词和防护,例如null,如trinithis的答案。
  • Set转换为列表。在大多数情况下,这很愚蠢,但是如果您仍然想遍历该集合,则效果很好。
  • 启用GHC's ViewPatterns extension,它提供语法糖来使用通常会进行模式匹配的访问器函数。
  • 避免首先进行此类检查-如果您有Set,将其视为一个集合,然后将其作为一个整体使用,以进行映射,过滤等。并非总是可能,但可以使代码更简洁较少的显式条件/迭代。

  • View 模式使您可以编写如下内容:
    foo (setView -> EmptySet) = []
    foo (setView -> NonEmpty set) = other_thing
    

    ...其中setView是您编写的函数。在这里并没有太大的收获,但是对于更复杂的伪模式可能很好

    为了避免显式检查,除了众所周知的set操作(例如unionintersection)之外,还应考虑使用filter中的partitionmapfoldData.Set函数。

    [0]:有关我正在使用的术语的定义,请参见this paper(警告:PDF)。

    关于haskell - 空集上的Haskell模式匹配,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/3327532/

    10-16 11:43