guard desugaring - haskell

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,

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

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"

Related

Errors while creating a power function

First of all, I want to say that I'm very very inexperienced with Haskell, and I know that I have done something (or multiple things) terribly wrong, been struggling for hours but I can't seem to find it.
power :: Int -> Int -> Int
power x y | y == 0 = 1
| x == 0 = 0
list = replicate y x
foldr (*) x list
main = print $ power 3 5
Error most of the time is either x and y not being passed to the replicate function or that foldr is a naked function, I understand what they both mean but have no idea on how I can pass the variables or come up with a solution.
You here created four functions: power, list, foldr and main. But you use variables x and y in the definition of the list function.
You can work with a where clause to specify subexpressions, for example:
power :: Int -> Int -> Int
power x y | y == 0 = 1
| x == 0 = 0
| otherwise = foldr (*) 1 list
where list = replicate y x
or perhaps more elegant with pattern matching:
power :: Int -> Int -> Int
power 0 _ = 0
power x y = foldr (*) 1 (replicate y x)
main = print $ power 3 5
Here we can also eliminate the case for x0, since our foldr starts working with 1, not x.
This algorithm is however not very efficient, since it is linear in the value of y. By checking recursively if the exponent is even or odd, you can make it faster. I leave this as an exercise.
You were very close! The main things that need to be fixed are:
When writing a definition with guards, the “fallback” case needs to be a guard as well, conventionally written with otherwise.
Recall that a definition without guards looks like this, with one left side (a name and parameter patterns/names) and one right side (an expression):
name patterns = expression
With guard conditions, there is one right-hand side for each guard:
name patterns | condition1 = expression1
| condition2 = expression2
…
| otherwise = expressionn
otherwise is really just an alias for True, that is, such a guard always matches. The only thing special about otherwise is that the compiler uses it as a hint when analysing whether a pattern match covers all possible cases.
In order to define a variable list, local to the definition of power, using the parameters x and y, you need to use either a let…in… expression, that is, let block in expression, or a where clause, equation where block. A block is a series of items (in this case, local definitions) which must all be written starting at the same column of indentation, or be delimited by explicit curly braces {…} and semicolons ;.
Using let…in… follows the structure of your original code pretty closely. I will adjust the indentation style to avoid needing to align anything, by putting a newline and a constant amount of indentation instead.
power :: Int -> Int -> Int
power x y
| y == 0 = 1
| x == 0 = 0
| otherwise = let
list = replicate y x
in foldr (*) x list
main :: IO ()
main = print $ power 3 5
Attaching a where clause to an equation is slightly more common than using a let…in… expression on the right side of an equation.
power :: Int -> Int -> Int
power x y
| y == 0 = 1
| x == 0 = 0
| otherwise = foldr (*) x list
where
list = replicate y x
main :: IO ()
main = print $ power 3 5
Note that in this case, there is a slight difference: the variable list is visible in all of the right-hand sides, although we only use it in one of them. With let list = … in e, list is only defined within e. In general, it’s helpful for readability to keep the scope of a variable as small as possible, although you can certainly go overboard:
a = …
where
b = …
where
c = …
where
d = …
-- If you see this much nesting, rethink!
If you run into issues with alignment and indentation, you can always use explicit delimiters instead. The code I wrote is equivalent to the following.
power :: Int -> Int -> Int; -- Begin ‘power’ signature.
power x y
| y == 0 = 1
| x == 0 = 0
| otherwise = let { -- Begin ‘let’ block.
list = replicate y x; -- End ‘list’ equation.
} in foldr (*) x list; -- End ‘let’ block, then end ‘power’ equation.
main :: IO (); -- Begin ‘main’ signature.
main = print $ power 3 5; -- End ‘main’ equation.
Or similarly with where { … }.

whats the advantage of using guards in Haskell?

count_instances :: (Int)->([Int])->Int
count_instances x [] = 0
count_instances x (t:ts)
| x==t = 1+(count_instances x ts)
| otherwise = count_instances x ts
i just want to know whats so good about using guards in this Question ?
A guard can be a way to write only one half of an if-then-else expression; you can omit the else and have a partial function.
-- Leave the function undefined for x /= y
foo x y | x == y = ...
You can do the same with a case statement, but it's more verbose
foo x y = case x == y of
True -> ...
It's also easier to list several unrelated conditions as a set of alternatives than it is with a nested if-then-else or case expressions.
foo x y | p1 x y = ...
foo x y | p2 x y = ...
foo x y | p3 x y = ...
foo x y = ...
vs
foo x y = if p1 x y then ...
else (if p2 x y then ...
else (if p3 x y then ... else ...))
Patterns with guards are probably the most concise way to write code that otherwise would require nested case/if expressions.
Not the least advantage is that a where clause applies to all the guards right hand sides. This is why your example could be even more concise:
count_instances :: (Int)->([Int])->Int
count_instances x [] = 0
count_instances x (t:ts)
| x==t = 1+rest
| otherwise = rest
where rest = count_instances x ts
A guard is haskell's most general conditional statement, like if/then/else in other languages.
Your code shows a straight forward implementation of counting contents of a list equal to a given parameter. This is a good example to learn how haskell's recursion works.
An alternative implementation would be
count_instances :: Int -> [Int] -> Int
count_instances i = length . filter (==i)
that reuses already existing functions from the Prelude module. This is shorter and probably more readable.

Haskell - guard inside case statement

I am going through Learn you a haskell book, and in Chapter 8 there is a snippet of code which looks like this
data LockerState = Taken | Free deriving (Eq, Show)
type Code = String
type LockerMap = Map.Map Int (LockerState, Code)
lookup' :: Int -> LockerMap -> Either String Code
lookup' num_ map_ =
case (Map.lookup num_ map_) of
Nothing -> Left $ "LockerNumber doesn't exist!"
Just (state, code) -> if state == Taken
then Left $ "LockerNumber already taken!"
else Right $ code
This works. However, I wanted to convert if/else block to guard statements like this:
lookup' :: Int -> LockerMap -> Either String Code
lookup' num_ map_ =
case (Map.lookup num_ map_) of
Nothing -> Left $ "LockerNumber doesn't exist!"
Just (state, code) ->
| state == Taken = Left $ "LockerNumber already taken!"
| otherwise = Right $ Code
This doesn't compile. It seems that usage of guards in Haskell is very restrictive/non intuitive. SO Ex1 SO Ex2. Is there a definite source which I can read which tells at which places I can use guards?
There are two places guards are allowed: function definitions and case expressions. In both contexts, guards appear after a pattern and before the body, so you use = in functions and -> in case branches, as usual:
divide x y
| y == 0 = Nothing
--------
| otherwise = Just (x / y)
-----------
positively mx = case mx of
Just x | x > 0 -> Just x
-------
_ -> Nothing
Guards are simply constraints for patterns, so Just x matches any non-Nothing value, but Just x | x > 0 only matches a Just whose wrapped value is also positive.
I suppose the definitive reference is the Haskell Report, specifically §3.13 Case Expressions and §4.4.3 Function and Pattern Bindings, which describe the syntax of guards and specify where they’re allowed.
In your code, you want:
Just (state, code)
| state == Taken -> Left "LockerNumber already taken!"
| otherwise -> Right code
This is also expressible with patterns alone:
Just (Taken, _) -> Left "LockerNumber already taken!"
Just (_, code) -> Right code

In Haskell, are guards or matchers preferable?

I'm learning Haskell, and it's not always clear to me when to use a matcher and when to use a guard. For certain scenarios it seems that matchers and guards can be used to achieve essentially the same ends. Are there some rules or heuristics for when it's better to use matches over guards or vice versa? Is one more performant than the other?
To illustrate what I'm getting at, here are a couple of silly examples I cooked up that seem to be equivalent, but one version uses matchers and the other uses guards:
listcheck :: [a] -> String
listcheck [] = "List is null :-("
listcheck a = "List is NOT null!!"
listcheck' a
| null a = "List is null :-("
| otherwise = "List is NOT null!!"
and
luckyseven :: Int -> String
luckyseven 7 = "SO LUCKY!"
luckyseven b = "Not so lucky :-/"
luckyseven' c
| c == 7 = "SO LUCKY!"
luckyseven' c = "Not so lucky :-/"
Thanks!
These can often be used interchangeably, but there are significant differences between the two. Pattern matching can only occur on constructors, so computations can not be performed inside of a pattern, while guards are simply multi-branch if-else statements. For example, I can't write a pattern equivalent of the following:
func :: Int -> Int
func x
| even x = 3 * x
| odd x = 7 * x -- alternatively "otherwise = 7 * x" to get rid of all those pesky compiler warnings
This just wouldn't be possible with just pattern matching. You also can't do things like
func :: Int -> Maybe String
func x
| x < 0 = Nothing
| x == 0 = Just "Zero"
| x < 20 = Just "Small"
| x < 100 = Just "Big"
| x < 1000 = Just "Huge"
| otherwise = Just "How did you count that high?"
Conversely, guards using ADTs don't give you much information without helper functions. If I had the type
data Expr
= Literal Int
| Add Expr Expr
| Mult Expr Expr
| Negate Expr
deriving (Eq, Show)
Using guards to write the equivalent of
eval :: Expr -> Int
eval (Literal i) = i
eval (Add e1 e2) = eval e1 + eval e2
eval (Mult e1 e2) = eval e1 * eval e2
eval (Negate e) = negate (eval e)
would be a lot more verbose, difficult, and annoying. In fact, at some level you'd have to resort to pattern matching to do things like
getLiteral :: Expr -> Int
getLiteral (Literal i) = i
getLiteral _ = error "Not a literal"
Which introduces functions that can error, which is bad. In this case, using pattern matching is much preferred over using guards.
For your particular examples, I'd go with pattern matching, but would use _ where possible:
listCheck :: [a] -> String
listCheck [] = "List is null :-("
listCheck _ = "List is NOT null!!"
and
luckySeven :: Int -> String
luckySeven 7 = "SO LUCKY!"
luckySeven _ = "Not so lucky :-/"
That emphasizes that if the list isn't empty, or the Int isn't 7, nothing else matters, and you aren't going to use its particular value to produce the function result. bheklilr has capably pointed out places where one choice or the other is definitely preferable.

Haskell syntax for 'or' in case expressions

In F#, I can use | to group cases when pattern matching. For example,
let rec factorial n =
match n with
| 0 | 1 -> 1 // like in this line
| _ -> n * factorial (n - 1)
What's the Haskell syntax for the same?
There is no way of sharing the same right hand side for different patterns. However, you can usually get around this by using guards instead of patterns, for example with elem.
foo x | x `elem` [A, C, G] = ...
| x `elem` [B, D, E] = ...
| otherwise = ...
with guards:
factorial n
| n < 2 = 1
| otherwise = n * (factorial (n - 1))
with pattern matching:
factorial 0 = 1
factorial 1 = 1
factorial n = n * (factorial (n - 1))
I'm not entirely familiar with F#, but in Haskell, case statements allow you to pattern match, binding variables to parts of an expression.
case listExpr of
(x:y:_) -> x+y
[x] -> x
_ -> 0
In the theoretical case that Haskell allowed the same:
It would therefore be problematic to allow multiple bindings
case listExpr of
(x:y:_) | [z] -> erm...which variables are bound? x and y? or z?
There are rare circumstances where it could work, by using the same binding:
unEither :: Either a a -> a
unEither val = case val of
Left v | Right v -> v
And as in the example you gave, it could work alright if you only match literals and do not bind anything:
case expr of
1 | 0 -> foo
_ -> bar
However:
As far as I know, Haskell does not have syntax like that. It does have guards, though, as mentioned by others.
Also note:
Using | in the case statement serves a different function in Haskell. The statement after the | acts as a guard.
case expr of
[x] | x < 2 -> 2
[x] -> 3
_ -> 4
So if this sort of syntax were to be introduced into Haskell, it would have to use something other than |. I would suggest using , (to whomever might feel like adding this to the Haskell spec.)
unEither val = case val of
Left v, Right v -> v
This currently produces "parse error on input ,"
Building on some of the above answers, you can (at least now) use guards to do multiple cases on a single line:
case name of
x | elem x ["Bob","John","Joe"] -> putStrLn "ok!"
"Frank" -> putStrLn "not ok!"
_ -> putStrLn "bad input!"
So, an input of "Bob", "John", or "Joe" would give you an "ok!", whereas "Frank" would be "not ok!", and everything else would be "bad input!"
Here's a fairly literal translation:
factorial n = case n of
0 -> sharedImpl
1 -> sharedImpl
n -> n * factorial (n - 1)
where
sharedImpl = 1
View patterns could also give you a literal translation.
isZeroOrOne n = case n of
0 -> True
1 -> True
_ -> False
factorial1 n = case n of
(isZeroOrOne -> True) -> 1
n -> n * factorial (n - 1)
factorial2 n = case n of
(\n -> case n of { 0 -> True; 1 -> True; _ -> False }) -> 1
n -> n * factorial (n - 1)
Not saying that these are better than the alternatives. Just pointing them out.

Resources