首页 文章

Haskell模式匹配空集

提问于
浏览
17

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

foo [] = []
foo x = other_thing

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

2 回答

  • 33

    好吧,你做不到 .

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

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

    • 使用布尔谓词和守卫,例如 null ,就像在trinithis的回答中一样 .

    • Set 转换为列表 . 大多数情况下这是愚蠢的,但如果你想要迭代整个集合,它运作良好 .

    • 启用GHC's ViewPatterns extension,它为使用模式匹配的访问器函数提供语法糖 .

    • 首先避免进行这类检查 - 如果你有一个 Set ,把它当成一个集合,并将它作为一个整体用于映射,过滤等 . 不总是可行,但可以导致更清晰的代码显式条件/迭代次数减少 .

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

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

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

    为避免显式检查,除了众所周知的设置操作(如 unionintersection )之外,请考虑在 Data.Set 中使用 filterpartitionmapfold 函数 .

    [0]: 有关术语的定义,请参阅this paper(警告:PDF),因为我正在使用它 .

  • 31
    import qualified Data.Set as Set
    
    foo set
      | Set.null set = bar
      | otherwise = baz
    

相关问题