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,
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"
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With