Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

guard desugaring

I often hear the phrase, guards are just syntactic sugar for if-then-else (or case statements).

Can somebody please desugar the following instance:

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

(The function is intentionally partial)

Thanks,

like image 934
Ozgur Avatar asked Nov 15 '10 03:11

Ozgur


2 Answers

The semantics of pattern matching are defined in the following section of the standard: Formal Semantics of Pattern Matching.

The step that is relevant to your question is c. As you can see, pattern matches with guards of the form

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

Are translated to pattern matches without guards as:

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

So pattern guards are defined in terms of if and "fallthrough" is implemented by binding the expression to a variable and then repeating it once in the else clause of the if and then in the pattern that you'd fall through to.

If there is no case to fall through to (as in your example) one will have been inserted by step b, which inserts a default case _ -> error "No match"

like image 170
sepp2k Avatar answered Nov 14 '22 22:11

sepp2k


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

The exact kind of error triggered by an unhandled case is not specified by the language definition, and varies from compiler to compiler.

edit: If there are multiple guards and/or patterns, each guard or pattern match goes into the non-matching part of the previous case.

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

produces

compare x y =
  if x == y
  then foo
  else if x /= y
       then bar
       else baz
like image 37
Heatsink Avatar answered Nov 14 '22 22:11

Heatsink