模式匹配存在重叠 - 运算符的模式匹配

6

我遇到了一种情况,我想在运算符上进行模式匹配。然而,在GHC中,这会引发一个“Pattern match(es) are overlapped”的错误。我无法理解为什么会出现这种情况。是否不允许在运算符上进行模式匹配?我认为,由于将运算符符号括在括号中将其转换为标识符,所以这应该是可以工作的。

test :: (Integer -> Integer -> Integer) -> String
test (+) = "plus"
test (-) = "minus"
test _ = "other"

我可以通过其他方式实现我的目标,只是我很好奇为什么这种方法不起作用。


9
第一行代码将匹配任何函数,并将其局部绑定到中缀运算符+上。因此,后续的行是多余的,这就是警告的原因。请注意,函数符号(中缀或非中缀)都可以通过模式匹配以这种方式进行本地重新绑定。只有大写构造函数(或带:-前缀的中缀构造函数)和字面量仅匹配它们自己,而且仅在一阶类型中才如此。Haskell 几乎没有办法检查函数的内涵属性:(seq除外),您只能通过应用它们来利用它们的外延属性。不允许问“这是 + 函数吗?”。 - pigworker
@pigworker,这就解释了为什么我会收到“此绑定遮盖了现有的前奏定义”消息。感谢您提供的信息。 - ars-longa-vita-brevis
1个回答

12

(+)(-) 不是类型为 Integer -> Integer -> Integer 的构造函数:

  • 它们不是构造函数名称
  • Integer -> Integer -> Integer 不是一种代数数据类型

因此,您的代码等同于使用任何其他变量名称绑定第一个参数,例如:

test foo = "plus"
test bar = "minus"
test _   = "other"
希望这样清楚表明,所有三个模式实际上都匹配任何内容(前两个绑定一些名称)。换句话说,第一个模式(在你的例子中是 foo 或 (+) )没有逃脱的可能性,这就是为什么它与剩下的两个重叠。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接