2009-10-03 93 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