[英]Unexpected pattern match in Haskell
在WinGHCI中加载以下示例后,我尝试评估
father p1
father p2
father p3
这三个表达式都产生相同的值:
Person "John" "Huston"
这怎么可能 ?
如果取消注释最后一行,则会收到以下警告:
test.hs:14:1: Warning:
Pattern match(es) are overlapped
In an equation for ‘father’: father p2 = ...
发生了什么 ?
data Person = Person String String deriving (Show)
p1 :: Person
p1 = Person "Charlie" "Chapling"
p2 :: Person
p2 = Person "John" "Huston"
p3 :: Person
p3 = Person "Frank" "Sinatra"
father :: Person -> Person
father p1 = p2
--father p2 = p3
您误会了
father p1 = p2
此子句中的变量p1
不引用您先前定义的p1
。 而是,它是一个新变量,并且子句匹配任何参数值。
您可以使用GHC 7.8的模式同义词执行您似乎正在尝试的操作:
pattern P1 = Person "Charlie" "Chaplin"
p2 :: Person
p2 = Person "John" "Huston"
p3 :: Person
p3 = Person "Frank" "Sinatra"
father :: Person -> Person
father P1 = p2
father _ = undefined
代码未经测试,因为我没有方便的GHC 7.8安装。
问题在于函数中的p1
匹配所有内容(您也可以编写x
不会有任何区别)。
我想您想做的是:
data Person = Person String String deriving (Show, Eq)
-- ... rest of your code - p1, p2, ...
father :: Person -> Person
father p
| p == p1 = p2
| p == p2 = p3
| otherwise = undefined -- what do you want to do here?
我建议根本不要使用这样的函数,而是要重新定义Person
以包括以下信息:
data Person = Person { givenName :: String, surName :: String, father :: Maybe Person }
deriving (Show, Eq)
您father
定义中的p1
变量与全局p1
没有任何关系。 模式匹配总是引入新变量,而从不使用全局变量。 因此,您的定义与此等效:
father aaa = p2
--father bbb = p3
您可以使用如下防护措施:
father p | p == p1 = p2
| p == p2 = p3
我还建议始终使用编译器选项-Wall
。 您可能会看到一些有趣的警告。 实际上,他们至少会为您指明正确的方向,这样您就不必再提出要求了。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.