GHC接受此代码,但它应该是非法语法(?)是否对发生的事情有任何猜测?
module Tilde where
~ x = x + 2 -- huh?
~ x +++ y = y * 3 -- this makes sense
(+++)
公式很有意义:它使用infix语法声明运算符,并在第一个参数上使用不可辩驳的模式匹配。
第一个“等式”看起来与开始时一样。但是没有运算符。如果我问
λ> :i ~
===> <interactive>:1:1: error: parse error on input `~'
λ> :i (~)
===> class (a ~ b) => (~) (a :: k) (b :: k)
-- Defined in `Data.Type.Equality'
instance [incoherent] forall k (a :: k) (b :: k). (a ~ b) => a ~ b
-- Defined in `Data.Type.Equality'
这是一个令人着迷的发现,但与此无关(?),我不能定义自己的类或运算符(~)
-Illegal binding of built-in syntax
,这并不奇怪。
哦:
λ> :i x
===> x :: Integer -- GHCi defaulting, presumably
,并尝试永远运行x
循环。所以奇怪实际上是在定义
x = x + 2
那~
在做什么?
答案 0 :(得分:11)
波浪号的作用与您在其他示例中的完全相同:它使模式不可辩驳(因此模式匹配不会失败)。当然,在两种情况下该模式都是不可辩驳的(作为一个普通变量,始终匹配),但这并没有使波浪号变为非法,只是不必要。
答案 1 :(得分:8)
写作
x = 5
创建一个名为x
的全局变量,该变量绑定到值5
。添加波浪号使模式匹配不可辩驳,但是它已经已经不可辩驳,因此没有太大意义。但是写这样的东西是合法的
(xs, ys) = span odd [1..10]
这定义了两个全局变量xs
和ys
,其中包含1到10之间的所有奇数和偶数。如果需要,甚至可以通过添加波浪号来使其变得无可辩驳。当然,这种模式不会失败(如果表达式的类型正确),因此没有意义。但是请考虑:
~(x:xs) = filter odd [1..10]
这定义了两个全局变量x
和xs
, if 过滤器返回至少一个结果。如果过滤器返回零结果,则模式匹配将失败。 (实际上,这意味着访问x
或xs
会引发模式匹配失败异常。)
您甚至可以写这样的东西,像
False = True
这个看似荒谬的声明模式-将模式False
与值True
匹配,并且两种方式都不起作用。这是该语言的晦涩之处之一。