Guards

Guard conditions allow you to express function branches using boolean expressions instead of pattern matching. Guard conditions are expressed with a set of aligned | characters followed by the condition and assignment to the function body.

If a condition evaluates to false it falls through to the next expression.

To catch all other cases it’s a convention to use an otherwise variable.

numberSize :: (Integral a) => a -> String
numberSize x
          | x < 0     = "Negative"
          | x <= 20   = "Twenty or less"
          | otherwise = "Bigger than twenty"

You can combine guard clauses with normal pattern matching.

maximum' :: (Ord a) => [a] -> a
maximum' [] = error "maximum of empty list"
maximum' [x] = x
maximum' (x:xs)
         | x > maxTail = x
         | otherwise = maxTail
         where maxTail = maximum' xs

Pattern matching with guards can also fall through to further patterned matched conditions if no otherwise case is specified. In the code below the first instance of fall doesn’t contain an otherwise clause for matching against values of x other than those less than 0 so the value falls through to the next definition of fall which is a direct pattern match with 10 and then a final guard clause statement which does have an otherwise.

fall  :: (Num  a, Eq  a, Ord  a) =>  a  -> [Char]
fall x
     | x <  0  =  "Less than zero"
fall 10  =  "x is 10"
fall x
     | x <  10  =  "Less than 10"
     | otherwise =  "Greater than 10"

You can insert any function that evaluates to a Bool as a guard condition because it simply whether something is true or false that controls whether a guard is executed or not. In the example below the p x invocation in the guard condition will either evaluate to True or False.

filter' :: (a -> Bool) -> [a] -> [a]
filter p (x:xs)
    | p x = x : filter p xs
    | otherwise = filter p xs