Last week we explored expressions and types, the fundamental building blocks of Haskell. These concepts revealed some major structural differences between Haskell and procedural languages. This week we’ll consider the implications of these ideas. We'll see how they affect syntactic constructs in Haskell.

## If Statements

Consider this Java function:

```
public int func(int input) {
int z = 5;
if (input % 2 == 0) {
z = 4;
}
return z * input;
}
```

Here we see a very basic if-statement. Under a certain condition, we change the value of `z`

. If the condition isn’t true we do nothing. But this **is not** how if statements work in Haskell! What lies inside the if statement is a command, and we compose our code with expressions and not commands!

In Haskell, an if-statement is an expression like anything else. This means it has to have a type! This constrains us in a couple ways. If the condition is true, we can supply an expression that will be the result. Then the type of the whole statement has the type of this expression. But what if the condition is not true? Can an expression be null or void? Most of the time no!* The following is rather problematic:

```
myValue :: Int -> ??? -- What type would this have if the condition is false?
myValue x = if x `mod` 2 == 0 then 5
```

This means that if-statements in Haskell **must** have an else branch. Furthermore, the else branch must have an expression that has the **same type** as in the true branch!

```
myValue :: Int -> Int -- Both the false and true branches are Int
myValue x = if x `mod` 2 == 0 then 5 else 3
```

Notice the real difference here. We’re used to saying “if x, do y”. But in Haskell, we assign an expression to be some value that may differ depending on a condition. So from a conceptual standpoint, the “if” is further inside the statement. This is one big hurdle to cross when first learning Haskell.

*Note: In monadic circumstances, a “null” value (represented as the unit type) can make sense. See `when`

and `unless`

.

## Where Statements

We've established that everything in Haskell is an expression. But we often use commands to assign values to intermediate variables. How can we do this in Haskell? After all, if a computation is complicated, we don’t want to describe it all on one line.

The `where`

statement fills this purpose. We can use `where`

, followed by any number of statements under to assign names to intermediate values!

```
mathFunc :: Int -> Int -> Int -> Int
mathFunc a b c = sum + product + difference
where
sum = a + b + c
product = a * b * c
difference = c - b - a
```

Statements in a `where`

clause can be in **any order**. They can **depend on each other**, as long as there are no dependency loops!

```
mathFunc :: Int -> Int -> Int -> Int
mathFunc a b c = sum + product + difference
where
product = a * b * c * sum
sum = a + b + c
difference = sum - b - product
```

## Let Statements

There’s a second way of describing intermediate variables! We can also use a `let`

statement, combined with `in`

. Unlike with `where`

, `let`

bindings must be in the right order. They can't depend on later values. Here’s the above function, written using `let`

:

```
mathFunc :: Int -> Int -> Int -> Int
mathFunc a b c =
let sum = a + b + c
product = a * b * c
difference = c - b - a
in sum + product + difference
```

Why do we have two ways of expressing the same concept? Well think about writing an essay. You'll often have terms you want to define for the reader. Sometimes, it makes more sense to define these **before** you use them. This is like using `let`

. But sometimes, you can use the expression first, and show the details of how you calculated it later. This is what `where`

is for! This especially works when the expression name is descriptive.

As a side note, there are also situations with monads where you can’t use `where`

and have to use `let`

. But that’s a topic for another time!

## Conclusion

If you’re new Haskell, hopefully these short articles are giving you some quick insights into the language. For more details, take a look at our Getting Started Checklist! If you think you’ve mastered the basics and want to learn how to organize a real project, you should take our free Stack mini-course. It will teach you how to use the Stack tool to keep your Haskell code straight.