2010-11-15 57 views
12

我经常听到这句话,卫兵只是if-then-else(或case语句)的语法糖。警卫desugaring

有人可以请desugar以下实例:

halfOf :: Int -> Int 
halfOf x | even x = div x 2 

(功能是有意部分)

感谢,

回答

3

模式匹配的语义是在标准的以下部分定义:Formal Semantics of Pattern Matching

与您的问题相关的步骤是c。正如你所看到的,图案的形式

case v of { p | g1 -> e1 ; ... 
       | gn -> en where { decls } 
      _  -> e' } 

都将转换为模式的警卫匹配无人看守匹配为:

case e' of 
{y -> 
    case v of { 
     p -> let { decls } in 
      if g1 then e1 ... else if gn then en else y ; 
     _ -> y }} 

所以模式警卫在if条款和“下通”定义的实现通过将表达式绑定到一个变量,然后在ifelse子句中重复一次,然后再按照您将遇到的模式重复一次。

如果告吹没有的情况下(如在你的例子)一个将被插入步骤b,这将插入一个默认的情况下_ -> error "No match"

+0

感谢您的参考。我很希望能够将分支标记为模式匹配错误,但是我明白为什么这种功能不是由该语言提供的。谢谢! – Ozgur 2010-11-15 18:39:37

12
halfOf x = 
    if even x 
    then div x 2 
    else error "Incomplete pattern match" 

确切类型的错误由未处理的情况下引发的是不是由语言定义指定的,并且因编译器而异。

编辑:如果有多个警卫和/或模式,则每个警卫或模式匹配进入前一个案例的不匹配部分。

compare x y 
    | x == y = foo 
    | x /= y = bar 
compare _ _ = baz 

产生

compare x y = 
    if x == y 
    then foo 
    else if x /= y 
     then bar 
     else baz 
+0

呀哈!这里有一个问题。这不是模式匹配错误。如果在该行之后还有另一个案例,会发生什么? – Ozgur 2010-11-15 03:59:20

+2

@Ozgur:如果你想要一个完整的答案,不要尝试用故意错误的问题来诱惑人。 – Akusete 2010-11-15 04:00:25

+0

@Ozgur:请参阅http://cs.anu.edu.au/Student/comp1100/haskell/tourofsyntax.html#Guards – Akusete 2010-11-15 04:01:59