1.1 Expressions are building blocks

Open up your terminal and start ghci.

$ ghci
GHCi, version 8.4.2: http://www.haskell.org/ghc/  :? for help
Prelude>

You can write arithmetic expressions in Haskell just as you would in math. For example, you can use the + operator to add two numbers together.

> 1 + 2
3

There are many arithmetic operators in Haskell. Below is a table of some commonly used ones.

operatormeaning
+add
-subtract
*multiply
/divide

You can also create more complex expressions with multiple operators and it will evaluate just like you would expect it to in math.

> 1 + 2 * 3
7

The result is 7 because of the precedence rules for addition and multiplication. Precedence rules tell us the order in which to perform the operations. Multiplication always happens first, as you learned in grade school. We can add parentheses to make the order of operations explicit. This is equivalent to the previous expression.

> 1 + (2 * 3)
7

If we want the addition to happen first instead of the multiplication, we can explicitly group that part of the expression.

> (1 + 2) * 3
9

As expected, we get 9. Try the following exercise.

Exercise 1

What is the result when you evaluate the expression below?

3 * 4 - 2

How can you modify this expression so that the order of operations is reversed?

Solution

If you follow the precedence rules, multiplication happens first, then subtraction, giving us:

(3 * 4) - 2

Which evaluates to 10.

To change the order of operations, we can use parentheses to explicitly group the subexpressions.

3 * (4 - 2)

Which evaluates to 6.

Besides arithmetic operators, Haskell also has named functions. If you want to calculate the square root of a number, you can use the sqrt function.

> sqrt 4
2.0

To apply a function, simply write the name of the function followed by a blank space, then list out the inputs to that function separated by blank spaces. This is just like using the arithmetic operators from earlier, except all of the inputs to the function are placed on the right-hand side. Looking at it another way, the arithmetic operators are also normal functions, but they are applied infix (inbetween the inputs) rather than prefix (before the inputs).

> sqrt (5 * 5)
5.0
> sqrt (5 * ((5 + 5) / 2))
5.0

You can construct expressions of arbitrary complexity by nesting expressions inside of other expressions, as shown above, using parentheses where necessary to specify the order of operations. Notice that if we leave out the parentheses from the first example above, we get a different result.

> sqrt 5 * 5
11.180339887498949

This is because function application associates from left to right, and function application has the highest precedence, higher than everything else. As a result, the expression above is equivalent to the following.

> (sqrt 5) * 5
11.180339887498949

Don’t worry if this looks complicated. All normal, prefix functions in Haskell have the same level of precedence, but some operators like the arithmetic ones we used earlier may differ. Most of the time, you don’t have to worry too much about it, unless you are using a lot of infix functions (operators). If you are ever in doubt about the precedence rules, you can always add more parentheses to be explicit about the order of operations that you want.