# Learn Haskell from Scratch: An Introduction to Functional Programming

Please note that this is work in progress. I intend to finish the first draft this summer (2020). However, I publish new parts when they're written.

Haskell is a lazy, functional programming language.

If you're coming from an imperative or object-oriented programming language, Haskell will throw you away. Instead of working with objects and changing their inner states, you'll work with functions that have no side effects. It's an entirely different programming paradigm.

Haskell is not a language you pick up and learn in an afternoon. However, learning Haskell can be rewarding. With Haskell, you'll learn to reason about your programs in a way you usually don't do. I can say for sure that learning Haskell made me learn to think.

If you're looking for a challenge, want programs that are easy to write and test, and are willing to learn for the sake of learning, Haskell is definitively the language for you. On the other hand, if you're looking for a quick fix and don't want to learn new things, immediately leave this page now ;)

Since you're still here, I guess you want to learn Haskell. But where do you start?

The best way to learn Haskell -- or any programming language for that matter -- is by writing code. This introduction is filled with many exercises, and I plan to add more. To summarize, read the text, check out the examples, and solve the exercises.

## Getting Started

Haskell comes with a handy interpreter called GHCi (Glasgow Haskell Compiler). To start GHCi, open a terminal shell and write `ghci`.

Exercise 1. GHCi can be used as a powerful calculator. Explore the following expressions in GHCi.

(a) `> 1 + 3`

(b) `> 6 * 7`

(c) `> 2 / 3`

(d) `> sin (pi/2)`

TODO

## Lists

We can do some awesome things with lists in Haskell.

Exercise 2. Explore the following expressions in GHCi.

(a) `> [1..10]`

(b) `> [1..]`

(c) `> [ x | x <- [1..10], mod x 2 == 0]`

## Functions

Everything in Haskell is a function in the mathematical sense. It takes some parameters and returns a value. The function will always return the same value, no matter when the function is called in the program, resulting in fewer bugs compared to imperative and object-oriented languages.

In an imperative language, the problem is solved by declaring the steps that need to be taken to solve it. However, in a functional language, the problem is solved by defining it. This forces the programmer to think about the program.

Let's write a function that calculates the area of a circle.

Recall that `A(r) = 2 * pi * r^2`.

Hmm.. so what are the types of this function? It takes a parameter r of type R (real) and returns a value of type R (real). In Haskell, we write it like this:

`area :: Floating a => a -> a`

Let's implement it...

`area r = 2 * pi * r^2`

Always try to declare types for your functions before implementing the function. It's something psychological, but it makes it so much easier to implement it correctly if you know what you're supposed to implement.

If you find it hard to figure out a function's types, you can let GHCi do it for you by using the `:type` command.

Exercise 3. Write down the types for the following functions and use GHCi to correct your answers.

Tip: To use GHCi to check types, write `:type f` where f is the function name.

Pro-tip: `:t` and `:type` are the same command.

(a) inc x = x + 1

(b) singleToPair a = (a,a)

(c) d x1 x2 = abs (x1 - x2)