当我加载一行文件时,GHCi究竟发生了什么:0 = 1?
我原以为这会产生错误,但似乎根本没有做任何事情。它有什么用吗?
我认为在GHCi中它只相当于“让0 = 1”。那是做什么的?
答案 0 :(得分:22)
0
绑定中的let
实际上是文字0
上的模式匹配。我最初也不确定发生了什么,但你可以通过使用严格的模式匹配来证实这一点:
Prelude> :set -XBangPatterns
Prelude> let !0 = 1 in 0
*** Exception: <interactive>:13:5-10: Non-exhaustive patterns in pattern binding
答案 1 :(得分:9)
如果您将失败的模式与名称x
匹配,您也可以强制它:
x @ 0 = 1
main = print x
产生错误:
FILE.hs: /path/to/FILE.hs:1:5-13: Irrefutable pattern failed for pattern x@0
答案 2 :(得分:3)
0=1
只是一种模式绑定。
Haskell 2010 Language Report describes
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
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
。