12

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

有人可以对以下实例进行脱糖:

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

(该功能是有意偏向的)

谢谢,

4

2 回答 2

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
于 2010-11-15T03:55:38.230 回答
4

模式匹配的语义在标准的以下部分定义:模式匹配的形式语义

与您的问题相关的步骤是 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并且“失败”是通过将表达式绑定到一个变量来实现的,然后在 the 的else子句中重复一次if,然后在你将失败的模式中重复一次。

如果没有案例可以通过(如您的示例),则步骤 b 将插入一个案例,该步骤将插入默认案例_ -> error "No match"

于 2010-11-15T14:59:56.470 回答