奇怪的波浪号语法

Ant*_*ntC 10 haskell

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

波浪号的作用与您在其他示例中所做的完全相同:它使模式不可辩驳(因此,模式匹配不会失败)。当然,在两种情况下该模式都是无可辩驳的(是一个始终匹配的纯变量),但这并没有使波浪号成为非法,只是不必要的。

  • @AntC正如您所观察到的,它根本不是一个函数,而是一个“整数”。您绝对不能编写等效的lambda表达式;所有lambda表达式都是函数。模式`x`与任何`Integer`匹配,并将`Integer`绑定到名字`x`;。因此,在〜x = x + 2中,名称x绑定到表达式x + 2上。 (2认同)

Mat*_*hid 8

写作

x = 5
Run Code Online (Sandbox Code Playgroud)

创建x绑定到值的全局变量5。添加波浪号使模式匹配不可辩驳,但是它已经不可辩驳,因此没有太大意义。但是写这样的东西是合法的

(xs, ys) = span odd [1..10]
Run Code Online (Sandbox Code Playgroud)

这定义了两个全局变量xsys,其中包含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,并且两种方式都不起作用。这是语言晦涩难懂的角落之一。