我通过将数据实现为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
,但我只想了解为什么这些代码不起作用?
这段代码
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
,因为这会指出局部变量对全局变量的影响。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句