与haskell文字等号

时间:2013-09-03 17:41:36

标签: haskell equality literals

当我加载一行文件时,GHCi究竟发生了什么:0 = 1?

我原以为这会产生错误,但似乎根本没有做任何事情。它有什么用吗?

我认为在GHCi中它只相当于“让0 = 1”。那是做什么的?

3 个答案:

答案 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