# Haskell – Guards vs. if-then-else vs. cases in Haskell

I have three functions that find the nth element of a list:

``````nthElement :: [a] -> Int -> Maybe a
nthElement [] a = Nothing
nthElement (x:xs) a | a <= 0 = Nothing
| a == 1 = Just x
| a > 1 = nthElement xs (a-1)

nthElementIf :: [a] -> Int -> Maybe a
nthElementIf [] a = Nothing
nthElementIf (x:xs) a = if a <= 1
then if a <= 0
then Nothing
else Just x -- a == 1
else nthElementIf xs (a-1)

nthElementCases :: [a] -> Int -> Maybe a
nthElementCases [] a = Nothing
nthElementCases (x:xs) a = case a <= 0 of
True -> Nothing
False -> case a == 1 of
True -> Just x
False -> nthElementCases xs (a-1)
``````

In my opinion, the first function is the best implementation because it is the most concise. But is there anything about the other two implementations that would make them preferable? And by extension, how would you choose between using guards, if-then-else statements, and cases?

#### Best Solution

From a technical standpoint, all three versions are equivalent.

That being said, my rule of thumb for styles is that if you can read it as if it was English (read `|` as "when", `| otherwise` as "otherwise" and `=` as "is" or "be"), you're probably doing something right.

`if..then..else` is for when you have one binary condition, or one single decision you need to make. Nested `if..then..else`-expressions are very uncommon in Haskell, and guards should almost always be used instead.

``````let absOfN =
if n < 0 -- Single binary expression
then -n
else  n
``````

Every `if..then..else` expression can be replaced by a guard if it is at the top level of a function, and this should generally be preferred, since you can add more cases more easily then:

``````abs n
| n < 0     = -n
| otherwise =  n
``````

`case..of` is for when you have multiple code paths, and every code path is guided by the structure of a value, i.e. via pattern matching. You very seldom match on `True` and `False`.

``````case mapping of
Constant v -> const v
Function f -> map f
``````

Guards complement `case..of` expressions, meaning that if you need to make complicated decisions depending on a value, first make decisions depending on the structure of your input, and then make decisions on the values in the structure.

``````handle  ExitSuccess = return ()
handle (ExitFailure code)
| code < 0  = putStrLn . ("internal error " ++) . show . abs \$ code
| otherwise = putStrLn . ("user error " ++)     . show       \$ code
``````

BTW. As a style tip, always make a newline after a `=` or before a `|` if the stuff after the `=`/`|` is too long for one line, or uses more lines for some other reason:

``````-- NO!
nthElement (x:xs) a | a <= 0 = Nothing
| a == 1 = Just x
| a > 1 = nthElement xs (a-1)

-- Much more compact! Look at those spaces we didn't waste!
nthElement (x:xs) a
| a <= 0    = Nothing
| a == 1    = Just x
| otherwise = nthElement xs (a-1)
``````