在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
答案 0 :(得分:3)
你误解了
的含义father p1 = p2
本节中的变量p1
未引用您之前定义的p1
。相反,它是一个新变量,该子句匹配任何参数值。
您可以使用GHC 7.8' pattern synonyms来做您正在尝试的事情:
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。
答案 1 :(得分:1)
问题是你的函数中的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)
答案 2 :(得分:0)
p1
定义中的father
变量与全局p1
没有任何关系。模式匹配总是引入新变量,从不使用全局变量。所以,你的定义等同于:
father aaa = p2
--father bbb = p3
你可以使用这样的守卫:
father p | p == p1 = p2
| p == p2 = p3
我还建议总是使用编译器选项-Wall
。您可能会看到一些有趣的警告。事实上,他们至少会指出你正确的方向,所以你可能不需要问SO。