Reputation: 463
What exactly happens in GHCi when I load a file with a line that says: 0=1 ?
I was expecting that this would give an error but it doesn't seem to do anything at all. Does it do anything?
I assume it's equivalent in GHCi to just saying "let 0=1". What does that do?
Upvotes: 19
Views: 640
Reputation: 3393
0=1
is just a pattern binding.
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
x
and y
are binding to Just 1
and 1.
Upvotes: 3
Reputation: 1308
If you give the failing pattern match a name x
, you can also force it like so:
x @ 0 = 1
main = print x
Which produces the error:
FILE.hs: /path/to/FILE.hs:1:5-13: Irrefutable pattern failed for pattern x@0
Upvotes: 9
Reputation: 16635
The 0
in your let
binding is actually a pattern match on the literal 0
. I wasn't sure what was going on at first too, but you can confirm this by using strict pattern matching like so:
Prelude> :set -XBangPatterns
Prelude> let !0 = 1 in 0
*** Exception: <interactive>:13:5-10: Non-exhaustive patterns in pattern binding
Upvotes: 23