18

当我加载带有以下行的文件时,GHCi 中究竟发生了什么: 0=1 ?

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

我认为它在 GHCi 中等同于说“让 0=1”。那有什么作用?

4

3 回答 3

23

0您的绑定let中的实际是文字上的模式匹配0。起初我也不确定发生了什么,但您可以通过使用严格的模式匹配来确认这一点,如下所示:

Prelude> :set -XBangPatterns 
Prelude> let !0 = 1 in 0
*** Exception: <interactive>:13:5-10: Non-exhaustive patterns in pattern binding
于 2013-09-03T18:03:55.257 回答
9

如果你给失败的模式匹配一​​个 name x,你也可以像这样强制它:

x @ 0 = 1
main = print x

这会产生错误:

FILE.hs: /path/to/FILE.hs:1:5-13: Irrefutable pattern failed for pattern x@0
于 2013-09-03T18:06:01.480 回答
3

0=1只是一个模式绑定。

Haskell 2010 语言报告描述


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.

于 2013-09-03T19:43:55.167 回答