当我加载带有以下行的文件时,GHCi 中究竟发生了什么: 0=1 ?
我原以为这会出错,但它似乎根本没有做任何事情。它有什么作用吗?
我认为它在 GHCi 中等同于说“让 0=1”。那有什么作用?
0
您的绑定let
中的实际是文字上的模式匹配0
。起初我也不确定发生了什么,但您可以通过使用严格的模式匹配来确认这一点,如下所示:
Prelude> :set -XBangPatterns
Prelude> let !0 = 1 in 0
*** Exception: <interactive>:13:5-10: Non-exhaustive patterns in pattern binding
如果你给失败的模式匹配一个 name x
,你也可以像这样强制它:
x @ 0 = 1
main = print x
这会产生错误:
FILE.hs: /path/to/FILE.hs:1:5-13: Irrefutable pattern failed for pattern x@0
0=1
只是一个模式绑定。
4.4.3 Function and Pattern Bindings
decl → (funlhs | pat) rhs
funlhs → var apat { apat }
| pat varop pat
| ( funlhs ) apat { apat }
rhs → = exp [where decls]
| gdrhs [where decls]
gdrhs → guards = exp [gdrhs]
guards → | guard1, …, guardn (n ≥ 1)
guard → pat
We distinguish two cases within this syntax: a pattern binding occurs when the left hand side is a pat; otherwise, the binding is called a function binding. Either binding may appear at the top-level of a module or within a where or let construct.
Patterns have this syntax:
pat → lpat qconop pat (infix constructor)
| lpat
lpat → apat
| - (integer | float) (negative literal)
| gcon apat1 … apatk (arity gcon = k, k ≥ 1)
apat → var [ @ apat] (as pattern)
| gcon (arity gcon = 0)
| qcon { fpat1 , … , fpatk } (labeled pattern, k ≥ 0)
| literal
| _ (wildcard)
| ( pat ) (parenthesized pattern)
| ( pat1 , … , patk ) (tuple pattern, k ≥ 2)
| [ pat1 , … , patk ] (list pattern, k ≥ 1)
| ~ apat (irrefutable pattern)
fpat → qvar = pat
Language Report also states
A pattern binding binds variables to values. A simple pattern binding has form p = e. The pattern p is matched “lazily” as an irrefutable pattern, as if there were an implicit ~ in front of it.
So, 0
in 0=1
is just a pattern. In essence, 0=1
and x=1
are the same thing. They are both pattern bindings.
The pattern is irrefutable, 0=1
does not fail, thus no error occurred and nothing happened.
If we have the following top level declaration. Something will happen.
x@(Just y) | z /= Nothing = Just 1
where
z = Just 0
.x
and y
are binding to Just 1
and 1