2010-07-25 84 views
16

我正在使用列表更改一些哈斯克尔代码集。我了解所需的一切,但我不确定如何在模式上进行模式匹配。列表有很好的文字语法,看起来很难用Set构造函数来模拟。例如,我可能有一些像这样的代码:空集上的哈斯克尔模式匹配

foo [] = [] 
foo x = other_thing 

我怎么可以这样写代码,因此它使用的不是列表设置?

回答

30

那么,你不能。

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

失去模式匹配抽象数据类型的能力是一个不愉快的附带损害位,但哦。您的选项大致为:

  • 使用布尔谓词和警卫,例如null,正如trinithis的回答。
  • Set转换为列表。大多数情况下这很愚蠢,但如果你想反复使用该设置,它就可以工作得很好。
  • 启用GHC's ViewPatterns extension,它提供使用访问器函数的语法糖,其中模式匹配通常会进行。
  • 避免首先进行这种检查 - 如果您有Set,请将其视为设置为,并将其作为整体用于映射,过滤等。不总是可行,但可以导致更清晰的代码,更少的显式条件/迭代。

查看模式将让你写的东西看起来是这样的:

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

...其中setView是你写的函数。不是真的在这里多增益的,但可以为更复杂的伪模式

为了避免明确的检查,除了众所周知的一套操作,如unionintersection,考虑利用漂亮的filterpartitionmapfold功能在Data.Set

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

+0

为ViewPatterns参考+1! – ShiDoiSi 2011-06-24 16:11:11

29
import qualified Data.Set as Set 

foo set 
    | Set.null set = bar 
    | otherwise = baz 
+1

+1简单回答 – 2010-07-25 07:46:15

+7

@simonjpascoe:等等,我们可以给*简单*答案?在这里,所有这一次,我认为最低有三段... – 2010-07-29 02:51:19