【问题标题】:Haskell Pattern Matching on the Empty Set空集上的 Haskell 模式匹配
【发布时间】:2010-07-25 00:47:43
【问题描述】:

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

foo [] = []
foo x = other_thing

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

【问题讨论】:

    标签: haskell pattern-matching


    【解决方案1】:
    import qualified Data.Set as Set
    
    foo set
      | Set.null set = bar
      | otherwise = baz
    

    【讨论】:

    • @simonjpascoe:等等,我们可以给出简单的答案吗?一直以来,我都认为至少有三段......
    【解决方案2】:

    嗯,你不能。

    Set 是一种抽象数据类型[0],它故意隐藏其内部表示,主要是为了保持不能静态的数据结构的不变量——由类型系统强制执行(具体来说,标准库Data.Set.Set 是二叉搜索树)。

    失去对抽象数据类型进行模式匹配的能力是一种令人不快的附带损害,但是哦,好吧。您的选择大致是:

    • 使用布尔谓词和保护,例如null,正如 trinithis 的回答。
    • Set 转换为列表。大多数情况下,这很愚蠢,但如果你想遍历集合,它就足够了。
    • 启用GHC's ViewPatterns extension,它为使用访问器函数提供了语法糖,通常会使用模式匹配。
    • 首先避免进行此类检查 - 如果您有 Set,请将其视为 set,并将其作为一个整体用于映射、过滤等。并非总是可行,但可以通过更少的显式条件/迭代生成更简洁的代码。

    查看模式可以让您编写如下所示的内容:

    foo (setView -> EmptySet) = []
    foo (setView -> NonEmpty set) = other_thing
    

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

    为了避免显式检查,除了众所周知的集合操作,如unionintersection,考虑使用Data.Set 中的filterpartitionmapfold 函数.

    [0]: 请参阅this paper(警告:PDF)了解我使用的术语的定义。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-11-13
      • 2021-05-22
      • 2017-05-08
      • 1970-01-01
      • 2019-03-01
      • 2016-10-29
      • 2017-10-12
      相关资源
      最近更新 更多