11

GHC 接受此代码,但它应该是非法语法(?)关于发生了什么的任何猜测?

module Tilde  where

~ x = x + 2             -- huh?

~ x +++ y = y * 3       -- this makes sense

这个(+++)等式是有道理的:它声明了一个运算符,使用中缀语法,并在第一个参数上使用了无可辩驳的模式匹配。

第一个“方程式”一开始看起来是一样的。但是没有运营商。如果我问

λ> :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

然后在~做什么?

4

2 回答 2

11

波浪号的作用与您在另一个示例中所做的完全一样:它使模式无可辩驳(因此模式匹配不会失败)。当然,在这两种情况下,模式已经是无可辩驳的(作为一个简单的变量,总是匹配的),但这并不意味着波浪号是非法的,只是不必要的。

于 2019-04-09T12:19:06.027 回答
9

写作

x = 5

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

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

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

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

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

甚至可以写出非常奇怪的东西,比如

False = True

这个看似荒谬的声明模式将模式False与 value匹配True,并且什么都不做。这是语言中那些晦涩的角落之一。

于 2019-04-09T14:18:43.723 回答