繁体   English   中英

Haskell中发生意外的模式匹配

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM