奇怪的波浪号语法

时间:2019-04-09 12:08:31

标签: haskell

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

~在做什么?

2 个答案:

答案 0 :(得分:11)

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

答案 1 :(得分:8)

写作

x = 5

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

(xs, ys) = span odd [1..10]

这定义了两个全局变量xsys,其中包含1到10之间的所有奇数和偶数。如果需要,甚至可以通过添加波浪号来使其变得无可辩驳。当然,这种模式不会失败(如果表达式的类型正确),因此没有意义。但是请考虑:

~(x:xs) = filter odd [1..10]

这定义了两个全局变量xxs if 过滤器返回至少一个结果。如果过滤器返回结果,则模式匹配将失败。 (实际上,这意味着访问xxs会引发模式匹配失败异常。)

您甚至可以这样的东西,像

False = True

这个看似荒谬的声明模式-将模式False与值True匹配,并且两种方式都不起作用。这是该语言的晦涩之处之一。