首页 > 解决方案 > 关于模式匹配的问题:为什么我不能对连接使用相同的参数?

问题描述

使用haskell教科书第32页编程的上下文

这个版本还有一个好处是,在第 12 章讨论的惰性求值下,如果第一个参数是 False,则返回结果 False,而不需要计算第二个参数。在实践中,前奏使用具​​有相同属性的方程定义 ∧,但仅使用第一个参数的值来选择应用哪个方程:

True ∧ b = b

False ∧ _ = False

也就是说,如果第一个参数为 True,则结果为第二个参数的值,如果第一个参数为 False,则结果为 False。请注意,出于技术原因,在一个方程中,同一名称不得用于多个参数。例如,运算符 ∧ 的以下定义基于以下观察:如果两个参数相等,则结果为相同值,否则结果为 False,但由于上述命名要求而无效:

问题

我不明白无法使用表达式的解释

b ∧ b = b

 __∧_ _= False

标签: haskell

解决方案


接受一个定义,例如

myFunction x x = ...
myFunction _ _ = ...

我们需要能够测试两个值是否相等。也就是说,给定两个任意值xy,我们需要能够计算是否x == y成立。

这可以在很多情况下完成,但(也许令人惊讶)不是全部。我们当然可以在xyBools 或Ints 时做到这一点,但不能在它们是Integer -> Bool或时做到这一点IO (),例如,因为我们无法真正测试无限多点上的函数或无限多世界上的 IO 动作。

因此,仅当变量以线性方式使用时,即当变量在模式中最多出现一次时,才允许模式匹配。所以,myFunction x x = ...是不允许的。

如果需要,when==被定义(如 on Bools)我们可以使用守卫来表达相同的想法:

myFunction x1 x2 | x1 == x2  = ....
                 | otherwise = ....

原则上,Haskell 可以使用 自动将非线性模式转换为带有保护的模式,如果手头的类型不可用==,可能会导致错误。==但是,它不是以这种方式定义的,如果需要,需要显式编写防护。

这种自动翻译可能很方便,但也可能是微妙错误的来源,如果一个人无意中重用了模式中的变量而没有意识到它。


推荐阅读