2010-07-25 35 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