diff --git a/src/02-what-is-functional-programming.md b/src/02-what-is-functional-programming.md
index 4d8372267cb5fd49b1c79cf124095e70c4cca66b..ed38d14d5ebfa24645e83d59accc726ce230b1af 100644
--- a/src/02-what-is-functional-programming.md
+++ b/src/02-what-is-functional-programming.md
@@ -20,7 +20,7 @@ do_another_thing(x, y)
 - In functional programming a program is no list of commands
 - More a *collection of definitions*
 
-```
+```haskell
 x = 4
 x = 2
 ```
diff --git a/src/04-first-types.md b/src/04-first-types.md
index 3f8f5159c7fe1a0e9b7f758cf3a003e09e0d5e96..9f6e1ef3fb34f375077d5e44a83919568aca08e0 100644
--- a/src/04-first-types.md
+++ b/src/04-first-types.md
@@ -8,7 +8,7 @@
 ## Basic Types in Haskell
 
 - `Int`: Integer numbers (`-1`, `0`, `30`)
-- `Boolean`: Truth values (`True`, `False`) (*capitalized!*)
+- `Bool`: Truth values (`True`, `False`) (*capitalized!*)
 - `Char`: Single characters (`'a'`, `'c'`)
 - `String`: Text (`"Hello"`, `"Cheese sandwich"`)
 - `a -> b`: Function with the
diff --git a/src/05-first-logic.md b/src/05-first-logic.md
index 280eeb7ede4e6a688c5f067fa3e5f61b59bfe829..c9cf4abe456a2dab521c93431757945546a44964 100644
--- a/src/05-first-logic.md
+++ b/src/05-first-logic.md
@@ -25,9 +25,9 @@ double x = "calculate it yourself"
 Pattern matching can "disassemble" values
 
 ```haskell
-tail :: [Int] -> [Int]
-tail [] = []
-tail (x:xs) = xs
+tail' :: [Int] -> [Int]
+tail' [] = []
+tail' (x:xs) = xs
 ```
 
 
diff --git a/src/06-finding-documentation.md b/src/06-finding-documentation.md
index 43bd511c6101c7392cbb00078697d614cacaf912..4c50c931e1162c23048261b71350c7a190bdfe6d 100644
--- a/src/06-finding-documentation.md
+++ b/src/06-finding-documentation.md
@@ -2,4 +2,11 @@
 
 ## Hoogle
 
-https://hoogle.haskell.org/
+Search for functions, types, typeclasses, modules, ... by name or type
+
+- <https://hoogle.haskell.org/> (general)
+- <https://www.stackage.org/> (for Stack)
+
+**Example:** I want a function that returns the first element of a list of numbers. I don't know the name of the function.
+
+But I can search for it by its type `[Int] -> Int`!
diff --git a/src/07-first-modules.md b/src/07-first-modules.md
new file mode 100644
index 0000000000000000000000000000000000000000..64ba2e7364b1bb06ad842861bc690183da5332ac
--- /dev/null
+++ b/src/07-first-modules.md
@@ -0,0 +1,13 @@
+# Modules
+
+## Modules
+
+You found a function on Hoogle that is in the module `Data.List`?
+
+```haskell
+import Data.List
+```
+
+By default only modules from the `base` package are available though.
+
+More about modules, packages and project management later!
diff --git a/src/07-simple-io.md b/src/07-simple-io.md
deleted file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000
diff --git a/src/08-higher-order.md b/src/08-higher-order.md
deleted file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000
diff --git a/src/08-simple-io.md b/src/08-simple-io.md
new file mode 100644
index 0000000000000000000000000000000000000000..dd0fbd2e635e23f68d689ea27feafec82996d72c
--- /dev/null
+++ b/src/08-simple-io.md
@@ -0,0 +1,13 @@
+# Simple IO
+
+## Simple IO
+
+How to make an executable/interactive program?
+
+```haskell
+main :: IO ()
+main = do
+  putStrLn "What is your name?"
+  name <- getLine
+  putStrLn ("Hello " ++ name ++ "!")
+```
diff --git a/src/09-higher-order.md b/src/09-higher-order.md
new file mode 100644
index 0000000000000000000000000000000000000000..72d54570a83adecff3727fbe4cc4f2bff9ff8a89
--- /dev/null
+++ b/src/09-higher-order.md
@@ -0,0 +1,5 @@
+# Higher Order Functions
+
+## Examples
+
+`map` & `filter`
diff --git a/src/10-types.md b/src/10-types.md
new file mode 100644
index 0000000000000000000000000000000000000000..bdef767fe4372cd0425bd5d215571e0ad5ccf8de
--- /dev/null
+++ b/src/10-types.md
@@ -0,0 +1,118 @@
+# Types
+
+## What is a type?
+
+Let's recapture: Types classify and restrict values.
+
+For example: The type of booleans `Bool`.
+
+A Boolean is always either `True` or `False`.
+
+## Sum Types
+
+We see: a type can allow multiple values. These are called *sum types*. They are defined using `data` and `|`.
+
+(Just accept `deriving Show` for now, it will be explained in the next chapter)
+
+```haskell
+data BaseColor = Red | Green | Blue deriving Show
+
+v1 :: BaseColor
+v1 = Green
+
+v2 :: BaseColor
+v2 = Blue
+```
+
+## Matching Sum Types
+
+Pattern maching now works!
+
+```haskell
+isPartOfYellow :: BaseColor -> Bool
+isPartOfYellow Red = True
+isPartOfYellow Green = True
+isPartOfYellow Blue = False
+```
+
+## Product Types
+
+But what if values should carry other values (like *"attributes"*)?
+
+Types can "include" other types. These are called *product types*. Sum and product types can be combined.
+
+```haskell
+data Degree = Bachelor | Master deriving Show
+data Student = Student String String Degree deriving Show
+data Device = Phone Int | Fridge String | Printer deriving Show
+
+me :: Student
+me = Student "Nicolas Lenz" "Computer Science" Master
+
+notMe :: Student
+notMe = Student "Horst-Dieter Müller" "Philosophy" Bachelor
+
+myDevice :: Device
+myDevice = Fridge "Bosch"
+```
+
+## Matching Product Types
+
+Pattern matching also works here.
+
+```haskell
+isComputerScienceMaster :: Student -> Bool
+isComputerScienceMaster (Student name "Computer Science" Master) = True
+isComputerScienceMaster (Student name field degree) = False
+```
+
+## Type Variables
+
+Previously:
+
+```haskell
+tail' :: [Int] -> [Int]
+tail' [] = []
+tail' (x:xs) = xs
+```
+
+Only works on `Int`. We can simply use a type variable!
+
+```haskell
+tail'' :: [a] -> [a]
+tail'' [] = []
+tail'' (x:xs) = xs
+```
+
+## Polymorphic Types
+
+Type variables can also be used in types.
+
+```haskell
+data Rated a = Good a | Bad a deriving Show
+
+rate :: Int -> Rated Int
+rate 42 = Good 42
+rate x = Bad x
+```
+
+## Recursive Types
+
+Remember lists of type `a`, `[a]`?
+
+A list is always either
+- *an empty list* or
+- *an element added in front of another list*.
+
+## Making the List Type
+
+```haskell
+data List a = Empty | Cons a (List a) deriving Show
+
+list :: List Int
+list = Cons 1 (Cons 2 (Cons 3 Empty))
+
+listToList :: [a] -> List a
+listToList [] = Empty
+listToList (x : xs) = Cons x (listToList xs)
+```
diff --git a/src/11-more-functions.md b/src/11-more-functions.md
new file mode 100644
index 0000000000000000000000000000000000000000..e5b203c3351c85dd6e54252dd3e174c2c33d2c77
--- /dev/null
+++ b/src/11-more-functions.md
@@ -0,0 +1,100 @@
+# More Functions
+
+## Comments
+
+```haskell
+x = 5  -- five
+
+{-
+multi-line comment!
+-}
+```
+
+## where & let
+
+`where` and `let` can be used for helper definitions.
+
+```haskell
+areaCircle :: Int -> Int
+areaCircle r = p * (r ^ 2) where p = 3
+
+areaCircle' :: Int -> Int
+areaCircle' r = let p = 3 in p * (r ^ 2)
+```
+
+`where` is only a syntactic construct, `let .. in ..` is an expression itself and can be used pretty much everywhere (like `if .. then .. else ..`).
+
+(Please use `pi` instead of `3`)
+
+## Guards
+
+Fancier if-alternative, like a switch
+
+```haskell
+rateNumber :: Int -> String
+rateNumber x
+  | x < 42 = "meh"
+  | x == 42 = "cool"
+  | x < 100 = "okay"
+  | otherwise = "great"
+```
+
+## case
+
+Pattern matching as expression
+
+```haskell
+isPartOfYellow :: BaseColor
+isPartOfYellow Red = True
+isPartOfYellow Green = True
+isPartOfYellow Blue = False
+
+isPartOfYellowCase :: BaseColor
+isPartOfYellowCase x = case x of
+  Red -> True
+  Green -> True
+  Blue -> False
+```
+
+## Pattern Matching vs. Conditions
+
+Note that function definitions and case definitions use pattern matching (e.g. can't use comparisons and functions, but disassemble values and assign parts to variables)
+
+ifs and guards check boolean conditions (e.g. can use comparisons and functions, but not assign to variables)
+
+## Wildcard
+
+You can discard unwanted values in pattern matching with the wildcard `_`:
+
+```haskell
+isComputerScienceMaster :: Student -> Bool
+isComputerScienceMaster (Student _ "Computer Science" Master) = True
+isComputerScienceMaster (Student _ _ _) = False
+```
+
+Only usable in patterns, i.e. on *left-hand side* of the `=`!
+
+## Infix
+
+You can use backticks \` to write functions between their arguments.
+
+## Example: QuickSort
+
+Sort a `[Int]` using QuickSort!
+
+- Take the first element of a list `p`
+- Return QuickSort recursively on all elements smaller than `p`
+- Then `p` itself
+- Then the recursively sorted bigger elements
+- An empty list is already sorted
+
+## A Solution
+
+```haskell
+quicksort :: [Int] -> [Int]
+quicksort [] = []
+quicksort (p:xs) = (quicksort lesser) ++ [p] ++ (quicksort greater)
+    where
+        lesser  = filter (< p) xs
+        greater = filter (>= p) xs
+```
diff --git a/src/12-typeclasses.md b/src/12-typeclasses.md
new file mode 100644
index 0000000000000000000000000000000000000000..62f6d906c422cf2b12ce1b8b5864807524e22401
--- /dev/null
+++ b/src/12-typeclasses.md
@@ -0,0 +1,20 @@
+# Typeclasses
+
+## What are typeclasses?
+
+Typeclasses in Haskell are a way of assigning "features" or "abilities" to types.
+
+Comparable to *interfaces* in object-oriented programming or *traits* in Rust. Caution: they have nothing to do with object-oriented classes!
+
+More concrete: Typeclasses ensure that types of that typeclass have certain functions available.
+
+## Example
+
+```haskell
+class Ratable a where
+  rate :: a -> String
+
+instance Ratable Int where
+  rate 42 = "Great"
+  rate _ = "Not so great"
+```