2009-10-03 63 views
0

其嵌套的名字,我有:模式匹配的數據類型和哈斯克爾

data Color = Blue | Green | Red | White | Yellow deriving (Eq,Ord) 

然後

data Term = Color | ... 
data Bag = Bag { 
color :: Color 
... 
} 

現在我希望能夠匹配,以確保給出的期限是顏色,如果是這樣檢查它的「價值」(藍/綠......)。類似這樣的:

func :: Term -> Bag -> Bool 
func (c :: Color) bag = (color bag) == c 

但(c :: Color)似乎不起作用。

+7

這似乎是一個共同的幾分初學者的誤解:(從數據'Color')名爲'Color'類型和命名'Color'構造(來自'數據Term = Color')在完全不同的命名空間中是完全不相關的。 – ephemient 2009-10-03 21:29:56

+1

@ephemien我會接受這個答案。 – 2009-10-04 07:16:55

回答

8
data Color = Blue | Green | Red | White | Yellow deriving (Eq,Ord) 

data Term = Color Color | Trash 

data Bag = Bag { 
    color :: Color 
} 

func (Color x) bag = (color bag) == x 

-- With the above, a call of func Trash something will fail. 
-- (unexhastive pattern match). You can add 

func Trash bag = False 

-- or 

func _ _ = False 

-- and it will work all time. 
2

這是一個有點文字的帳號,與sdcvvc的內容沒有什麼不同,我認爲。

 
data Color = Blue | Green | Red | White | Yellow deriving (Eq,Ord,Show) 
data Size = Small | Medium | Large deriving (Eq, Ord, Show) 

data Term = TColor Color | TSize Size | Trash deriving Show 
data Bag = Bag {color :: Color , size :: Size} deriving Show 

請注意,與sdcvvc不同,我使用了「TColor Color」。這是沒有什麼不同,因爲typechecker可以告訴一個是已經建立的類型,另一個是新類型的新構造函數,即使它們拼寫相同。這只是少了一點混淆。現在,像「色彩」這樣的東西現在不會那麼少見,但是在像Bird這樣的老書中,「Haskell的FP入門」,他不會做這種事情。這有點像Haskeller對諸如「\ file - > readFile文件」這樣的流行風格,它有其優點,但有可能讓人困惑,而且看起來很新。以前它只是\ x - > readFile x或其他東西。

 
theMrsThatcher :: Bag 
theMrsThatcher = Bag Blue Large 

theMrsRobinson :: Bag 
theMrsRobinson = Bag {color = Green, size = Small} -- to use the other syntax 

colorCheck :: Term -> Bag -> Bool 
colorCheck (TColor c) b = True 
colorCheck (TSize s) b = False -- as sdcvvc says, this and 
colorCheck Trash b = False  -- the next clause can be replaced by 
           -- colorCheck _ _ = False 

還請注意,在colorCheck袋是無關緊要的。從你說的原因不清楚你爲什麼需要中間類型術語。

 
colorTest :: Color -> Bag -> Bool 
colorTest c b = color b == c 

colorCheckTest :: Term -> Bag -> Bool 
colorCheckTest (TColor c) b = color b == c 
colorCheckTest (TSize s) b = False -- as above, the last clauses are 
colorCheckTest Trash b = False  -- wordier than need be since any 
             -- but the first pattern is a loser. 

結果:

 
*Main> colorCheck (TColor Blue) theMrsRobinson 
True 
*Main> colorCheck (TColor Blue) theMrsThatcher 
True 
*Main> colorCheckTest (TColor Blue) theMrsRobinson 
False 
*Main> colorCheckTest (TColor Blue) theMrsThatcher 
True 
*Main> colorTest Blue theMrsThatcher 
True 
*Main> colorTest Blue theMrsRobinson 
False