Boolean condition #
Pattern matching has limitations.
Examples. No pattern can match:
- integers greater than 2,
- odd integers,
- etc.
For more expressive conditions, programming language usually rely on Boolean expressions.
In Haskell #
Boolean expression #
We have seen how to define a Boolean operator (precisely, the Boolean operator “AND”) with patterns in Haskell.
This is not necessary: Haskell provides native implementations, similar to their counterparts in Java (and many programming languages). They include:
- conjunction, noted
&&, - disjunction, noted
||, - negation, noted
not.
Examples.
3 < 2 && 3 > 5evaluates toFalsenot (3 > 5 || True)evaluates toFalse
Guards #
Syntax. A guard is a Boolean expression preceded with a
|.
Similarly to patterns, guards let us define a function on a case-by-case basis.
The first guard that evaluates to True determines the return value.
Example. The following function maps an integer to its absolute value:
abs :: Int -> Int -- if x >= 0, then return it abs x | x >= 0 = x -- if x < 0, then return - x | x < 0 = - xThere are two guard in this definition:
| x >= 0| x < 0
Note. The function above is equivalent to
abs :: Int -> Int abs x | x >= 0 = x | True = - x
Syntax. Haskell provides the keyword
otherwiseas an alias forTrue.
Example. The function above can be written
abs :: Int -> Int abs x | x >= 0 = x | otherwise = - x
Simplify the following function.
dummyComp :: Int -> Int -> Bool
dummyComp x y | x <= y = True
| x < y || x + 1 <= y = False
| otherwise = True
dummyComp :: Int -> Int -> Bool
dummyComp _ _ = True
Syntax. A guard can be used after a pattern.
Example.
-- Maps a number n to the nth Fibonacci number fib :: Int -> Int fib 1 = 1 -- pattern only fib n | n > 1 = fib (n-1) + fib (n-2) -- pattern + guard | otherwise = 0
To go further. A pattern can also be used inside a guard, with a left arrow (
<-).This can be helpful to pattern match the result of a function call. We will not cover this syntax here. Instead, we already introduced pattern matching within a case expression or an alias definition, which can serve the same purpose.
Conditional statement #
Haskell also supports “if/then/else” expressions, similar to their counterparts in imperative languages (like Java).
Example. The following function maps:
- a (strictly) positive integer to
1,0to0, and- a negative integer to
-1.signum :: Int -> Int signum x = if x > 0 then 1 else if x == 0 then 0 else -1
Warning. As opposed to Java, the
elseis mandatory.
Example. The following function definition is not valid syntactically:
invalid:: Int -> Int invalid _ = if True then 0 -- missing `else`
In Java #
You should already be familiar with Boolean expressions in Java, as well as their usage in:
- conditional statements (
if (<expression>){<instructions>} else {<instructions>}), - loop termination condition (
while (<expression>){<instructions>}), - switch statements,
- etc.