Alex Rivera | Logout

Which is the preferred method for writing "guards"?

Asked 2011-12-10T23:22:14.137
13

I’ve created a function in which I can use (as far as I know) case expressions or guards.

foo a b c = case a of 1 -> [...]
                      2 -> [...]
                      3 -> [...] 
                      [...]
                      otherwise -> error "..."

or

foo a b c | a == 1 = [...]
          | a == 2 = [...]
          | a == 3 = [...] 
          | [...]
          | otherwise = error "..."

So, the question is: which of those 2 (case or guards) are “better” coding? Are both basically the same?

Edit
Report

1 Answer

13

The first one is considered better style, for 2 reasons.

First of all: Many people would say that it looks better, since you don't have to type out all of the ==. This is a very subjective reason, of course. Also, you would normally not even introduce a new case statement, but just match the arguments in the function argument list like so:

foo 1 b c = ... -- etc
...
foo _ b c = ... -- for the "otherwise" part

This makes the code even more compact and readable, which many people like.

Secondly, there actually is a semantic difference. Imagine that you have a data type like this:

data Cake = Apple | Cheese | Cream

If you use the first method, you match against the constructors in the case..of expression:

case a of
  Apple -> "fruit"
  _     -> "not fruit"

However, if you try to do a guarded expression of some sort, like this:

| a == Apple = "fruit"
| otherwise  = "not fruit"

... it won't actually work, because the Cake type doesn't have an Eq instance, so you can't use == to compare two values. Introducing an Eq instance (with deriving (Eq) after the data definition) is not always wanted, so not having to do it in this case might be significant.

answered 2011-12-10T23:37:57.683

Your Answer