函数定义的顺序在列表模式中是否重要
Does the order of function definition matter in list patterns
所以这些函数命令在 GHCI 中有不同的行为:
safetailpatter xs = tail xs
safetailpatter [] = []
safetailpatter [] = []
safetailpatter xs = tail xs
前者传入时产生如下警告和以下错误[]
ex3.hs:66:1: warning: [-Woverlapping-patterns]
Pattern match is redundant
In an equation for ‘safetailpatter’: safetailpatter [] = ...
*** Exception: Prelude.tail: empty list
因此定义的顺序很重要,为什么?我不明白为什么前者重叠而后者不重叠,因为给出了相同的定义。
xs
也匹配空列表,因此如果将 safetailpatter xs
放在第一个,safetailpatter []
将永远不会被调用。
我对 Haskell 很陌生,但我认为这就是正在发生的事情。
所以,当你先放置 safetailpatter xs
然后用一个空列表调用它时,你试图在空列表上调用 tail
,你得到了异常。
至于
Pattern match is redundant
In an equation for ‘safetailpatter’: safetailpatter [] = ...
我认为这基本上就是我上面描述的意思,它抱怨声明是多余的,因为当你把后者放在第一位时,safetailpatter []
已经被 safetailpatter xs
覆盖了。
这就是为什么您应该始终将 _
放在模式匹配定义末尾的原因,否则您将永远不会调用其余模式:
myF (x:xs) = -- ....
myF _ = -- ... -> Right
myF _ = -- ... -> Wrong, now no the bellow definition will never get called
myF (x:xs) = -- ....
模式按顺序匹配。但是,这里发生的事情是您实际上并不是 safetailpatter xs
上的部分匹配。
在常规英语中 safetailpatter xs = tail xs
表示:任何变量上的 safetailpatter 是该变量的尾部。
你要匹配的是:safetailpatter (x:xs) = tail (x:xs)
,它代表:safetailpatter 当应用于至少有一个元素的列表时,是这样一个列表的尾部
知道这一点,在代码中
safetailpatter xs = tail xs
safetailpatter [] = []
将按顺序检查,并且由于第一个等式与任何列表输入相匹配,您会在 []
上得到 运行 时间错误。而
safetailpatter (x:xs) = tail xs
safetailpatter [] = []
按顺序匹配,由于 []
不匹配第一个等式,它将 运行 第二个,没有 运行 时间错误
编辑
正如@chepner 所说,这是调用无可辩驳的模式。这意味着模式匹配正在发生,但没有失败的机会。与匹配 _
相同
所以这些函数命令在 GHCI 中有不同的行为:
safetailpatter xs = tail xs
safetailpatter [] = []
safetailpatter [] = []
safetailpatter xs = tail xs
前者传入时产生如下警告和以下错误[]
ex3.hs:66:1: warning: [-Woverlapping-patterns]
Pattern match is redundant
In an equation for ‘safetailpatter’: safetailpatter [] = ...
*** Exception: Prelude.tail: empty list
因此定义的顺序很重要,为什么?我不明白为什么前者重叠而后者不重叠,因为给出了相同的定义。
xs
也匹配空列表,因此如果将 safetailpatter xs
放在第一个,safetailpatter []
将永远不会被调用。
我对 Haskell 很陌生,但我认为这就是正在发生的事情。
所以,当你先放置 safetailpatter xs
然后用一个空列表调用它时,你试图在空列表上调用 tail
,你得到了异常。
至于
Pattern match is redundant
In an equation for ‘safetailpatter’: safetailpatter [] = ...
我认为这基本上就是我上面描述的意思,它抱怨声明是多余的,因为当你把后者放在第一位时,safetailpatter []
已经被 safetailpatter xs
覆盖了。
这就是为什么您应该始终将 _
放在模式匹配定义末尾的原因,否则您将永远不会调用其余模式:
myF (x:xs) = -- ....
myF _ = -- ... -> Right
myF _ = -- ... -> Wrong, now no the bellow definition will never get called
myF (x:xs) = -- ....
模式按顺序匹配。但是,这里发生的事情是您实际上并不是 safetailpatter xs
上的部分匹配。
在常规英语中 safetailpatter xs = tail xs
表示:任何变量上的 safetailpatter 是该变量的尾部。
你要匹配的是:safetailpatter (x:xs) = tail (x:xs)
,它代表:safetailpatter 当应用于至少有一个元素的列表时,是这样一个列表的尾部
知道这一点,在代码中
safetailpatter xs = tail xs
safetailpatter [] = []
将按顺序检查,并且由于第一个等式与任何列表输入相匹配,您会在 []
上得到 运行 时间错误。而
safetailpatter (x:xs) = tail xs
safetailpatter [] = []
按顺序匹配,由于 []
不匹配第一个等式,它将 运行 第二个,没有 运行 时间错误
编辑
正如@chepner 所说,这是调用无可辩驳的模式。这意味着模式匹配正在发生,但没有失败的机会。与匹配 _