GHC接受此代码,但它应该是非法的语法(?)关于正在发生什么的任何猜测?
module Tilde where
~ x = x + 2 -- huh?
~ x +++ y = y * 3 -- this makes sense
Run Code Online (Sandbox Code Playgroud)
该(+++)方程式很有意义:它使用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'
Run Code Online (Sandbox Code Playgroud)
这是一个令人着迷的发现,但是与它无关(?)我不能定义自己的类或运算符(~)- Illegal binding of built-in syntax毫不奇怪。
哦:
?> :i x
===> x :: Integer -- GHCi defaulting, presumably
Run Code Online (Sandbox Code Playgroud)
并尝试x永远运行循环。所以奇怪实际上是在定义
x = x + 2
Run Code Online (Sandbox Code Playgroud)
那是~怎么回事
Dan*_*ner 11
波浪号的作用与您在其他示例中所做的完全相同:它使模式不可辩驳(因此,模式匹配不会失败)。当然,在两种情况下该模式都是无可辩驳的(是一个始终匹配的纯变量),但这并没有使波浪号成为非法,只是不必要的。
写作
x = 5
Run Code Online (Sandbox Code Playgroud)
创建x绑定到值的全局变量5。添加波浪号使模式匹配不可辩驳,但是它已经不可辩驳,因此没有太大意义。但是写这样的东西是合法的
(xs, ys) = span odd [1..10]
Run Code Online (Sandbox Code Playgroud)
这定义了两个全局变量xs和ys,其中包含1到10之间的所有奇数和偶数。如果需要,甚至可以通过添加波浪号来使此变量不可辩驳。当然,这种模式不会失败(如果表达式的类型正确),因此没有意义。但是请考虑:
~(x:xs) = filter odd [1..10]
Run Code Online (Sandbox Code Playgroud)
如果过滤器返回至少一个结果,则定义两个全局变量x和。如果过滤器将返回零结果,则模式匹配将失败。(实际上,这意味着访问或将引发模式匹配失败异常。)xsxxs
您甚至可以写出非常奇怪的东西,例如
False = True
Run Code Online (Sandbox Code Playgroud)
这种看似荒谬的声明模式将模式False与value 匹配True,并且两种方式都不起作用。这是语言晦涩难懂的角落之一。