1

私は持っている:

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) は機能していないようです。

4

2 に答える 2

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.
于 2009-10-03T21:27:11.550 に答える
3

Here is a somewhat wordier account, no different in content from sdcvvc's, I think.

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

Notice that unlike sdcvvc I used "TColor Color". It's no different since the typechecker can tell that one is an already established type the other is a new constructor of a new type, even if they're spelled the same. It's just little less confusing. Something like "Color Color" would not be so uncommon these days, but in a older book like Bird's "Intro to FP with Haskell," he wouldn't do this sort of thing. It's a bit like the Haskeller's vogue for things like "\file -> readFile file" which has its advantages, but is potentially confusing and it seems pretty recent; formerly it would have been just \x -> readFile x or something.

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

Note also that in colorCheck the bag is irrelevant. It isn't clear from what you say why you need the intermediate type Term.

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.

Results:

*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  
于 2009-10-05T02:57:39.633 に答える