我通过将数据实现为Enum
来尝试以下代码。
而且,我有一个问题,就是将Enum
替换为newtype
。
这是我的测试代码。
newtype Fruit = Fruit Int deriving (Eq)
apple = Fruit 0
banana = Fruit 1
grape = Fruit 2
orange = Fruit 3
instance Show Fruit where
show apple = "Apple"
show banana = "Banana"
show grape = "Grape"
show orange = "Orange"
show _ = "Fruit"
test =
map show [apple, banana, grape, orange, (Fruit 5)]
我预计评估的test
将是["Apple","Banana","Grape","Orange","Fruit"]
,但它是["Apple","Apple","Apple","Apple","Apple"]
我认为它变量可能不适用于模式匹配,但我再次尝试case
,如:
-- Fails: everything is "Apple"
instance Show Fruit where
show g = case g of
apple -> "Apple"
banana -> "Banana"
grape -> "Grape"
orange -> "Orange"
_ -> "Fruit"
为了确认我的临时性,我再次尝试使用下一个代码。
-- Fails: Works only for apple/banana. Variable does not work!
instance Show Fruit where
show (Fruit 0) = "Apple"
show (Fruit 1) = "Banana"
show grape = "Grape"
show orange = "Orange"
show _ = "Fruit"
我可以得到["Apple","Banana","Grape","Grape","Grape"]
好吧,我可以编写代码来实现Enum
,但我只是想了解为什么代码不能正常工作?
答案 0 :(得分:5)
此代码
instance Show Fruit where
show apple = "Apple"
show banana = "Banana"
show grape = "Grape"
show orange = "Orange"
show _ = "Fruit"
相当于
instance Show Fruit where
show x = "Apple"
show y = "Banana"
show z = "Grape"
show w = "Orange"
show _ = "Fruit"
因为它声明了名为apple, ...
的新变量,这些变量会影响全局定义的变量,而不会以任何方式与它们相关。
尝试改为
instance Show Fruit where
show x | x == apple = "Apple"
| x == banana = "Banana"
| x == grape = "Grape"
| x == orange = "Orange"
| otherwise = "Fruit"
要记住的拇指规则是:在模式中,所有变量都是由模式定义的局部变量。
我建议使用-Wall
打开警告,因为这会指出本地变量对全局变量的影响。
答案 1 :(得分:0)
您似乎尝试做的另一种方法是使用PatternSynonyms。