Skip to content

Instantly share code, notes, and snippets.

@amadiyawa
Forked from mikehaertl/gist:3258427
Created January 23, 2019 19:14
Show Gist options
  • Select an option

  • Save amadiyawa/2b65a57554b21b24feb638dee5eb6573 to your computer and use it in GitHub Desktop.

Select an option

Save amadiyawa/2b65a57554b21b24feb638dee5eb6573 to your computer and use it in GitHub Desktop.

Revisions

  1. @mikehaertl mikehaertl revised this gist Aug 10, 2012. No changes.
  2. @mikehaertl mikehaertl revised this gist Aug 8, 2012. 1 changed file with 15 additions and 1 deletion.
    16 changes: 15 additions & 1 deletion gistfile1.md
    Original file line number Diff line number Diff line change
    @@ -892,6 +892,20 @@ f . g = \x -> f (g x)

    ```haskell
    map (\x -> negate (abs x)) [5,-3,-6,7,-3,2,-19,24]
    -- with function composition
    map (\xs -> negate (sum (tail xs))) [[1..5],[3..6],[1..7]]
    sum (replicate 5 (max 6.7 8.9))
    replicate 100 (product (map (*3) (zipWith max [1,2,3,4,5] [4,5,6,7,8])))
    -- same with function composition
    map (negate . abs) [5,-3,-6,7,-3,2,-19,24]
    map (negate . sum . tail) [[1..5],[3..6],[1..7]]
    sum . replicate 5 . max 6.7 $ 8.9
    replicate 100 . product . map (*3) . zipWith max [1,2,3,4,5] $ [4,5,6,7,8]
    ```

    * A common use case for function composition is defining function in so called *point free* style. It's when we write `sum' = foldl (+) 0` instead of `sum' xs = foldl (+) 0 xs` (omitting the `xs`).

    ```haskell
    fn x = ceiling (negate (tan (cos (max 50 x))))
    -- in point free style
    fn = ceiling . negate . tan . cos . max 50
    ```
  3. @mikehaertl mikehaertl revised this gist Aug 8, 2012. 1 changed file with 43 additions and 1 deletion.
    44 changes: 43 additions & 1 deletion gistfile1.md
    Original file line number Diff line number Diff line change
    @@ -840,6 +840,8 @@ sum = foldl1 (+)

    reverse' :: [a] -> [a]
    reverse' = foldl (\acc x -> x : acc) []
    -- alternative
    reverse' = foldl (flip (:)) []

    product' :: (Num a) => [a] -> a
    product' = foldr1 (*)
    @@ -852,4 +854,44 @@ sum = foldl1 (+)

    last' :: [a] -> a
    last' = foldl1 (\_ x -> x)
    ```
    ```

    * **scanl** and **scanr** are like `foldl` and `foldr` but they also give all intermediate results back

    ```haskell
    scanl (+) 0 [3,5,2,1] ([0,3,8,10,11])
    scanr (+) 0 [3,5,2,1] ([11,8,3,1,0])
    scanl1 (\acc x -> if x > acc then x else acc) [3,2,9,2,1] ([3,3,9,9,9])
    scanl (flip (:)) [] [3,2,1] ([[],[3],[2,3],[1,2,3]])
    ```

    * *How many elements does it take for the sum of the roots of all natural numbers to exceed 1000?*

    ```haskell
    sqrtSums :: Int
    sqrtSums = length (takeWhile (<1000) (scanl1 (+) (map sqrt [1..]))) + 1
    ```

    * The **function application** function **$** looks like

    ```haskell
    ($) :: (a -> b) -> a -> b
    f $ x = f x
    ```

    It has lowest precedencde and thus can often be used instead of parentheses: `sum $ map sqrt [1..130]` instead of `sum (map sqrt [1..130])` or `sum $ filter (> 10) $ map (*2) [2..10]` instead of `sum (filter (> 10) (map (*2) [2..10]))`.

    It also allows to map function application to a list of functions like `map ($ 3) [(4+), (10*), (^2), sqrt]`.

    * **Function composition** is done with the **.** function. If called with two functions `f` and `g` it returns a new function. This function is like calling `f` with argument `x` and then `g` with that result: `f( g(x) )`.

    ```haskell
    (.) :: (b -> c) -> (a -> b) -> a -> c
    f . g = \x -> f (g x)
    ```

    ```haskell
    map (\x -> negate (abs x)) [5,-3,-6,7,-3,2,-19,24]
    -- with function composition
    map (negate . abs) [5,-3,-6,7,-3,2,-19,24]
    ```
  4. @mikehaertl mikehaertl revised this gist Aug 8, 2012. 1 changed file with 13 additions and 13 deletions.
    26 changes: 13 additions & 13 deletions gistfile1.md
    Original file line number Diff line number Diff line change
    @@ -835,21 +835,21 @@ sum = foldl1 (+)
    * Fold examples

    ```haskell
    maximum' :: (Ord a) => [a] -> a
    maximum' = foldr1 (\x acc -> if x > acc then x else acc)
    maximum' :: (Ord a) => [a] -> a
    maximum' = foldr1 (\x acc -> if x > acc then x else acc)

    reverse' :: [a] -> [a]
    reverse' = foldl (\acc x -> x : acc) []
    reverse' :: [a] -> [a]
    reverse' = foldl (\acc x -> x : acc) []

    product' :: (Num a) => [a] -> a
    product' = foldr1 (*)
    product' :: (Num a) => [a] -> a
    product' = foldr1 (*)

    filter' :: (a -> Bool) -> [a] -> [a]
    filter' p = foldr (\x acc -> if p x then x : acc else acc) []
    filter' :: (a -> Bool) -> [a] -> [a]
    filter' p = foldr (\x acc -> if p x then x : acc else acc) []

    head' :: [a] -> a
    head' = foldr1 (\x _ -> x)
    head' :: [a] -> a
    head' = foldr1 (\x _ -> x)

    last' :: [a] -> a
    last' = foldl1 (\_ x -> x)
    ```
    last' :: [a] -> a
    last' = foldl1 (\_ x -> x)
    ```
  5. @mikehaertl mikehaertl revised this gist Aug 8, 2012. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion gistfile1.md
    Original file line number Diff line number Diff line change
    @@ -837,7 +837,7 @@ sum = foldl1 (+)
    ```haskell
    maximum' :: (Ord a) => [a] -> a
    maximum' = foldr1 (\x acc -> if x > acc then x else acc)

    reverse' :: [a] -> [a]
    reverse' = foldl (\acc x -> x : acc) []

  6. @mikehaertl mikehaertl revised this gist Aug 8, 2012. 1 changed file with 39 additions and 3 deletions.
    42 changes: 39 additions & 3 deletions gistfile1.md
    Original file line number Diff line number Diff line change
    @@ -796,9 +796,9 @@ separated parameters, and a `->` that points at the function body:
    Sometimes lambdas are used even if that is not neccessary, like `map (\x -> x + 3) [1,6,3,2]`
    instead of more readable `map (+3) [1,6,3,2]`.

    * **Folds** take a binary function a start value and a list as parameter. The binary function is called with the accumulator and the first (or last) element from the list and produces a new accumulator. Then it's called again with this new accumulator and the next list element.
    * **Folds** take a binary function a start value and a list as parameter. The binary function is called with the accumulator and the first (or last) element from the list and produces a new accumulator. Then it's called again with this new accumulator and the next list element. Whenever you want to traverse a list to return something, chances are you want a fold.

    **foldl** or **left fold** folds up a list from the left side.
    * **foldl** or **left fold** folds up a list from the left side.

    ```haskell
    sum' :: (Num a) => [a] -> a
    @@ -812,8 +812,44 @@ sum' :: (Num a) => [a] -> a
    sum' = foldl (+) 0
    ```

    ```
    ```haskell
    elem' :: (Eq a) => a -> [a] -> Bool
    elem' y ys = foldl (\acc x -> if x == y then True else acc) False ys
    ```

    * **foldr** does a **right fold**. Here the parameters to the binary function are flipped.

    ```haskell
    map' :: (a -> b) -> [a] -> [b]
    map' f xs = foldr (\x acc -> f x : acc) [] xs
    ```

    We could also use `foldl` with the function `\acc x -> acc ++ [f x]`. But `++` is much more expensive than `:`. Right folds are usually used to build up lists. Right folds also work with infinite lists whereas left folds don't.

    * **foldl1** and **foldr1** work like `foldl` and `foldr` but use the first (or last) list element as starting value. They don't work with emtpy lists.

    ```haskell
    sum = foldl1 (+)
    ```

    * Fold examples

    ```haskell
    maximum' :: (Ord a) => [a] -> a
    maximum' = foldr1 (\x acc -> if x > acc then x else acc)

    reverse' :: [a] -> [a]
    reverse' = foldl (\acc x -> x : acc) []

    product' :: (Num a) => [a] -> a
    product' = foldr1 (*)

    filter' :: (a -> Bool) -> [a] -> [a]
    filter' p = foldr (\x acc -> if p x then x : acc else acc) []

    head' :: [a] -> a
    head' = foldr1 (\x _ -> x)

    last' :: [a] -> a
    last' = foldl1 (\_ x -> x)
    ```
  7. @mikehaertl mikehaertl revised this gist Aug 7, 2012. 1 changed file with 25 additions and 1 deletion.
    26 changes: 25 additions & 1 deletion gistfile1.md
    Original file line number Diff line number Diff line change
    @@ -789,7 +789,31 @@ separated parameters, and a `->` that points at the function body:
    zipWith (\a b -> (a * 30 + 3) / b) [5,4,3,2,1] [1,2,3,4,5]

    map (\(a,b) -> a + b) [(1,2),(3,5),(6,3),(2,6),(2,5)]

    flip' f = \x y -> f y x
    ```

    Sometimes lambdas are used even if that is not neccessary, like `map (\x -> x + 3) [1,6,3,2]`
    instead of more readable `map (+3) [1,6,3,2]`.
    instead of more readable `map (+3) [1,6,3,2]`.

    * **Folds** take a binary function a start value and a list as parameter. The binary function is called with the accumulator and the first (or last) element from the list and produces a new accumulator. Then it's called again with this new accumulator and the next list element.

    **foldl** or **left fold** folds up a list from the left side.

    ```haskell
    sum' :: (Num a) => [a] -> a
    sum' xs = foldl (\acc x -> acc + x) 0 xs
    ```

    In the beginning the binary function is called with `acc` value `0` and the first list element. The lambda function `(\acc x -> acc + x)` is the same as `(+)` and we can omit `xs` because `foo a = bar b a` can be written as `foo = bar b`:

    ```haskell
    sum' :: (Num a) => [a] -> a
    sum' = foldl (+) 0
    ```

    ```
    elem' :: (Eq a) => a -> [a] -> Bool
    elem' y ys = foldl (\acc x -> if x == y then True else acc) False ys
    ```

  8. @mikehaertl mikehaertl revised this gist Aug 6, 2012. 1 changed file with 0 additions and 1 deletion.
    1 change: 0 additions & 1 deletion gistfile1.md
    Original file line number Diff line number Diff line change
    @@ -789,7 +789,6 @@ separated parameters, and a `->` that points at the function body:
    zipWith (\a b -> (a * 30 + 3) / b) [5,4,3,2,1] [1,2,3,4,5]

    map (\(a,b) -> a + b) [(1,2),(3,5),(6,3),(2,6),(2,5)]

    ```

    Sometimes lambdas are used even if that is not neccessary, like `map (\x -> x + 3) [1,6,3,2]`
  9. @mikehaertl mikehaertl revised this gist Aug 6, 2012. 1 changed file with 4 additions and 4 deletions.
    8 changes: 4 additions & 4 deletions gistfile1.md
    Original file line number Diff line number Diff line change
    @@ -783,12 +783,12 @@ sum (takeWhile (<10000) [n^2 | n <- [1..], odd (n^2)])
    separated parameters, and a `->` that points at the function body:

    ```haskell
    numLongChains :: Int
    numLongChains = length (filter (\xs -> length xs > 15) (map chain [1..100]))
    numLongChains :: Int
    numLongChains = length (filter (\xs -> length xs > 15) (map chain [1..100]))

    zipWith (\a b -> (a * 30 + 3) / b) [5,4,3,2,1] [1,2,3,4,5]
    zipWith (\a b -> (a * 30 + 3) / b) [5,4,3,2,1] [1,2,3,4,5]

    map (\(a,b) -> a + b) [(1,2),(3,5),(6,3),(2,6),(2,5)]
    map (\(a,b) -> a + b) [(1,2),(3,5),(6,3),(2,6),(2,5)]

    ```

  10. @mikehaertl mikehaertl revised this gist Aug 5, 2012. 1 changed file with 17 additions and 1 deletion.
    18 changes: 17 additions & 1 deletion gistfile1.md
    Original file line number Diff line number Diff line change
    @@ -777,4 +777,20 @@ sum (takeWhile (<10000) [n^2 | n <- [1..], odd (n^2)])
    numLongChains :: Int
    numLongChains = length (filter isLong (map chain [1..100]))
    where isLong xs = length xs > 15
    ```
    ```

    * **Lambdas** are anonymous functions. They are defined with a `\`, followed by space
    separated parameters, and a `->` that points at the function body:

    ```haskell
    numLongChains :: Int
    numLongChains = length (filter (\xs -> length xs > 15) (map chain [1..100]))

    zipWith (\a b -> (a * 30 + 3) / b) [5,4,3,2,1] [1,2,3,4,5]

    map (\(a,b) -> a + b) [(1,2),(3,5),(6,3),(2,6),(2,5)]

    ```

    Sometimes lambdas are used even if that is not neccessary, like `map (\x -> x + 3) [1,6,3,2]`
    instead of more readable `map (+3) [1,6,3,2]`.
  11. @mikehaertl mikehaertl revised this gist Aug 5, 2012. 1 changed file with 27 additions and 0 deletions.
    27 changes: 27 additions & 0 deletions gistfile1.md
    Original file line number Diff line number Diff line change
    @@ -751,3 +751,30 @@ let notNull x = not (null x) in filter notNull [[1,2,3],[],[2,2]] ([[1,2,3],[2
    in smallerSorted ++ [x] ++ biggerSorted
    ```

    * The **takeWhile** function takes a predicate function and a list. It returns elements from the list until the predicate becomes `False`.

    Sum of all odd squares that are smaller than `10000`

    ```haskell
    sum (takeWhile (<10000) (filter odd (map (^2) [1..])))
    ```

    Alternative with list comprehension

    ```haskell
    sum (takeWhile (<10000) [n^2 | n <- [1..], odd (n^2)])
    ```

    * Example: The Collatz sequence starts at any number. If the number is even, it's divided by `2`. If it is odd it is multiplied by `3` and `1` is added. In any case the chain continues at this new number until the sequence reaches `1`. Question: For all starting numbers between 1 and 100, how many chains have a length greater than 15?

    ```haskell
    chain :: (Integral a) => a -> [a]
    chain 1 = [1]
    chain n
    | even n = n:chain (n `div` 2)
    | odd n = n:chain (n*3 + 1)

    numLongChains :: Int
    numLongChains = length (filter isLong (map chain [1..100]))
    where isLong xs = length xs > 15
    ```
  12. @mikehaertl mikehaertl revised this gist Aug 5, 2012. 1 changed file with 66 additions and 2 deletions.
    68 changes: 66 additions & 2 deletions gistfile1.md
    Original file line number Diff line number Diff line change
    @@ -126,7 +126,7 @@ someString = "Some string"
    [20,19..15] ([20,19,18,17,16,15])
    ```

    * List methods
    * List related functions

    - `head [5,4,3]` : first element of a list (`5`)
    - `tail [5,4,3]` : tail without head (`[4,3]`)
    @@ -197,7 +197,7 @@ someString = "Some string"
    [("Johnny", "Walker", 38), ("Kate", "Middleton", 27)]
    ```

    * Tuple functions
    * Tuple related functions

    - `fst (8,11)` : returns first component of a pair (`8`)
    - `snd (9,"Hey")` : returns second component of a pair (`"Hey"`)
    @@ -686,4 +686,68 @@ zipWith' (+) [4,2,5,6] [2,6,2,3] ([6,8,7,9])
    zipWith' max [6,3,2,1] [7,3,1,5] ([7,3,2,5])
    zipWith' (++) ["foo ", "bar "] ["fighters", "hoppers"] (["foo fighters", "bar hoppers"])
    zipWith' (*) (replicate 5 2) [1..] ([2,4,6,8,10])
    zipWith' (zipWith'(*)) [ [1,2], [3,4] ] [ [2,3], [4,5] ] ([[2,6],[12,20]])
    ```

    * `flip` takes a function and returns a function where the first two parameters are flipped

    ```haskell
    flip' :: (a -> b -> c) -> (b -> a -> c)
    flip' f = g
    where g x y = f y x
    ```

    Or even shorter

    ```haskell
    flip' :: (a -> b -> c) -> b -> a -> c
    flip' f y x = f x y
    ```

    ```haskell
    zipWith (flip' div) [2,2..] [10,8,6,4,2] ( [5,4,3,2,1] )
    ```

    * The **map** function takes a function and a list and returns a list with the function applied to every element

    ```haskell
    map :: (a -> b) -> [a] -> [b]
    map _ [] = []
    map f (x:xs) = f x : map f xs
    ```

    ```haskell
    map (+3) [1,5,3,1,6] ([4,8,6,4,9])
    map (++ "!") ["BIFF", "BANG"] (["BIFF!","BANG!"])
    map (replicate 2) [3..6] ([[3,3],[4,4],[5,5],[6,6]])
    map (map (^2)) [[1,2],[3,4,5]] ([[1,4],[9,16,25]])
    map fst [(1,2),(3,5)] ([1,3])
    ```

    * The **filter** function takes a function that filters elements from a list

    ```haskell
    filter :: (a -> bool) -> [a] -> [a]
    filter _ [] = []
    filter p (x:xs)
    | p x = x : filter p xs
    | otherwhise = filter p xs
    ```

    ```haskell
    filter (>3) [1,5,3,6] ([5,6])
    filter even [1..10] ([1,2,4,6,8,10])
    let notNull x = not (null x) in filter notNull [[1,2,3],[],[2,2]] ([[1,2,3],[2,2]])
    ```

    Alternative quicksort implementation

    ```haskell
    quicksort :: (Ord a) => [a] -> [a]
    quicksort [] = []
    quicksort (x:xs) =
    let smallerSorted = quicksort (filter (<=x) xs)
    biggerSorted = quicksort (filter (>x) xs)
    in smallerSorted ++ [x] ++ biggerSorted
    ```

  13. @mikehaertl mikehaertl revised this gist Aug 4, 2012. 1 changed file with 45 additions and 1 deletion.
    46 changes: 45 additions & 1 deletion gistfile1.md
    Original file line number Diff line number Diff line change
    @@ -630,16 +630,60 @@ multWithEighteen = multTwoWithNine 2
    multWithEighteen 10 (180)
    ```

    A function that compares the argument with `100` could be written like:

    ```haskell
    compareWithHundred :: (Num a, Ord a) => a -> Ordering
    compareWithHundred x = compare 100 x
    ```

    The part `compare 100` returns. It returns a function that takes a number and compares it with `100`.
    The part `compare 100` returns a function that takes a number and compares it with `100`.
    The above thus can be rewritten as

    ```haskell
    compareWithHundred :: (Num a, Ord a) => a -> Ordering
    compareWithHundred = compare 100
    ```

    * More examples

    ```haskell
    divideByTen :: (Floating a) => a -> a
    divideByTen = (/10)
    ```

    ```haskell
    isUpperAlphanum :: Char -> Bool
    isUpperAlphanum = (`elem` ['A'..'Z'])
    ```

    * The type declaration of functions that take functions look different

    ```haskell
    applyTwice :: (a -> a) -> a -> a
    applyTwice f x = f (f x)
    ```

    ```haskell
    applyTwice (+3) 10 (13)
    applyTwice (++ " HAHA") "HEY" ("HEY HAHA HAHA")
    applyTwice ("HAHA " ++) "HEY" ("HAHA HAHA HEY")
    applyTwice (multThree 2 2) 9 (144)
    applyTwice (3:) [1] ([3,3,1])
    ```

    * `zipWith` takes a function and two lists and applies the function on each two items of both lists to get a new list

    ```haskell
    zipWith' :: (a -> b -> c) -> [a] -> [b] -> [c]
    zipWith' _ [] _ = []
    zipWith' _ _ [] = []
    zipWith' f (x:xs) (y:ys) = f x y : zipWith' f xs ys
    ```

    ```haskell
    zipWith' (+) [4,2,5,6] [2,6,2,3] ([6,8,7,9])
    zipWith' max [6,3,2,1] [7,3,1,5] ([7,3,2,5])
    zipWith' (++) ["foo ", "bar "] ["fighters", "hoppers"] (["foo fighters", "bar hoppers"])
    zipWith' (*) (replicate 5 2) [1..] ([2,4,6,8,10])
    ```
  14. @mikehaertl mikehaertl revised this gist Aug 4, 2012. 1 changed file with 31 additions and 0 deletions.
    31 changes: 31 additions & 0 deletions gistfile1.md
    Original file line number Diff line number Diff line change
    @@ -612,3 +612,34 @@ max :: (Ord a) => a -> (a -> a)
    ```

    It takes an `a` and returns a function, which takes another `a` and returns an `a`.

    * If a function is callaed with not all parameters we get back a **partially applied** function.

    ```haskell
    multThree :: (Num a) => a -> a -> a -> a
    multThree x y z = x * y * z
    ```

    When we do `multThree 3 5 9` it's actually `((multThree 3) 5) 9` or
    `multThree :: (Num a) => a -> (a -> (a -> a))`. First `multThree 3` is applied, which returns a function. This function takes a single argument and returns another function. This other function again takes a single argument and returns the parameter multiplied by `15`. This allows us to do things like

    ```haskell
    multTwoWithNine = multThree 9
    multTwoWithNine 2 3 (54)
    multWithEighteen = multTwoWithNine 2
    multWithEighteen 10 (180)
    ```

    ```haskell
    compareWithHundred :: (Num a, Ord a) => a -> Ordering
    compareWithHundred x = compare 100 x
    ```

    The part `compare 100` returns. It returns a function that takes a number and compares it with `100`.
    The above thus can be rewritten as

    ```haskell
    compareWithHundred :: (Num a, Ord a) => a -> Ordering
    compareWithHundred = compare 100

    ```
  15. @mikehaertl mikehaertl revised this gist Aug 4, 2012. 1 changed file with 1 addition and 0 deletions.
    1 change: 1 addition & 0 deletions gistfile1.md
    Original file line number Diff line number Diff line change
    @@ -609,5 +609,6 @@ be written in two equivalent ways:
    ```haskell
    max :: (Ord a) => a -> a -> a
    max :: (Ord a) => a -> (a -> a)
    ```

    It takes an `a` and returns a function, which takes another `a` and returns an `a`.
  16. @mikehaertl mikehaertl revised this gist Aug 4, 2012. 1 changed file with 10 additions and 1 deletion.
    11 changes: 10 additions & 1 deletion gistfile1.md
    Original file line number Diff line number Diff line change
    @@ -266,7 +266,7 @@ from the declaration:

    * Related functions

    - `5 \`compare\` 3` : takes two `Ord` members of same type and returns a `Ordering` (`GT`)
    - ``5 `compare` 3`` : takes two `Ord` members of same type and returns a `Ordering` (`GT`)
    - `show 3` : takes a `Show` and returns a `String` (`"3"`)
    - `read "True"` : takes a `Read` and returns a `Read` (`True`)
    - `succ LT` : takes a `Enum` and returns next element (`GT`)
    @@ -602,3 +602,12 @@ These calls are equivalent:
    max 4 5
    (max 4) 5
    ```

    * A space between two things ist simply **function application**. The type of `max` can
    be written in two equivalent ways:

    ```haskell
    max :: (Ord a) => a -> a -> a
    max :: (Ord a) => a -> (a -> a)

    It takes an `a` and returns a function, which takes another `a` and returns an `a`.
  17. @mikehaertl mikehaertl revised this gist Aug 4, 2012. 1 changed file with 53 additions and 53 deletions.
    106 changes: 53 additions & 53 deletions gistfile1.md
    Original file line number Diff line number Diff line change
    @@ -113,14 +113,14 @@ someString = "Some string"

    * List ranges are defined with `..`:

    ```
    ```haskell
    [1..20]
    ['a'..'z']
    ```

    * Ranges can define a step size

    ```
    ```haskell
    [2,4..20] ([2,4,6,8,10,12,16,18,20])
    [3,6..20] ([3,6,9,12,15,18])
    [20,19..15] ([20,19,18,17,16,15])
    @@ -148,50 +148,50 @@ someString = "Some string"

    * **List comprehensions** are similar to mathematical equations

    ```
    ```haskell
    [x*2 | x <- [1..5]] ([2,4,6,8,10])
    ```

    * **Predicates** are conditions for list comprehensions

    ```
    ```haskell
    [x*2 | x <- [1..5], x*2 >= 5] ([6,8,10])
    ```

    * There can be more than one predicates

    ```
    ```haskell
    [ x | x <- [10..20], x /= 10, x /= 15, x /= 19]
    ```

    * Comprehensions can be put inside a function

    ```
    ```haskell
    boomBangs xs = [if x < 10 then "BOOM!" else "BANG!" | x <- xs, odd x]
    ```

    * Comprehensions can draw from several lists, which multiplies the lengths

    ```
    ```haskell
    [ x*y | x <- [2,3], y <- [3,4,5]] ([6,8,10,9,12,15])
    ```

    * `_` is a dummy placeholder for a unused value

    ```
    ```haskell
    length' xs = sum [1 | _ <- xs]
    ```

    * List comprehensions can be nested

    ```
    ```haskell
    let xxs = [[1,2,3],[2,3,4],[4,5]]
    [ [x | x <- xs, even x] | xs <- xxs] ([[2],[2,4],[4]]
    ```

    * **Tuples** can contain several types, but for the type of two Tuples to be the same, the number and types of their elements must match

    ```
    ```haskell
    (1,2)
    [(1,2), (3,2), (4,9)]
    [("Johnny", "Walker", 38), ("Kate", "Middleton", 27)]
    @@ -211,7 +211,7 @@ someString = "Some string"

    * Use `:t` to get a type of something

    ```
    ```haskell
    :t 'a' ('a' :: Char)
    :t "HELLO" ("HELLO" :: [Char])
    :t (True, 'a') ( (True,'a') :: (Bool, Char) )
    @@ -220,7 +220,7 @@ someString = "Some string"
    * All functions should use a **type declaration** with `::` ("has type of").
    Multiple arguments are also separeted with `->` just like the type declaration itself.

    ```
    ```haskell
    removeUppercase :: [Char] -> [Char]
    removeUppercase :: String -> String (same as above)
    addThree :: Int -> Int -> Int -> Int
    @@ -241,7 +241,7 @@ Multiple arguments are also separeted with `->` just like the type declaration i
    * **Type variables** can be used in function declarations. They stand for a type.
    Without a class constraint they mean "any type"

    ```
    ```haskell
    :t head (head :: [a] -> a)
    :t fst (fst :: (a, b) -> a)
    ```
    @@ -250,7 +250,7 @@ Without a class constraint they mean "any type"
    it implements that class' behavior. The `=>` symbol separates the **class constraint**
    from the declaration:

    ```
    ```haskell
    :t (==) ( (==) :: (Eq a) => a -> a -> Bool )
    ```

    @@ -277,7 +277,7 @@ from the declaration:

    * *Type annotations* define the type of ambiguous expressions

    ```
    ```haskell
    (read "5" :: Float) * 4
    ```

    @@ -289,44 +289,44 @@ from the declaration:
    matches a specified pattern. The first matching pattern is executed. There should always
    be a catch-all pattern at the end

    ```
    ```haskell
    lucky :: (Integral a) => a -> String
    lucky 7 = "LUCKY NUMBER SEVEN!"
    lucky x = "Sorry, you're out of luck, pal!"
    ```

    ```
    ```haskell
    factorial :: (Integral a) => a -> a
    factorial 0 = 1
    factorial n = n * factorial (n - 1)
    ```

    ```
    ```haskell
    addVectors :: (Num a) => (a, a) -> (a, a) -> (a, a)
    addVectors (x1, y1) (x2, y2) = (x1 + x2, y1 + y2)
    ```

    ```
    ```haskell
    head' :: [a] -> a
    head' [] = error "Can't call head on an empty list, dummy!"
    head' (x:_) = x
    ```

    ```
    ```haskell
    tell :: (Show a) => [a] -> String
    tell [] = "The list is empty"
    tell (x:[]) = "The list has one element: " ++ show x
    tell (x:y:[]) = "The list has two elements: " ++ show x ++ " and " ++ show y
    tell (x:y:_) = "This list is long. The first two elements are: " ++ show x ++ " and " ++ show y
    ```

    ```
    ```haskell
    length' :: (Num b) => [a] -> b
    length' [] = 0
    length' (_:xs) = 1 + length' xs
    ```

    ```
    ```haskell
    sum' :: (Num a) => [a] -> a
    sum' [] = 0
    sum' (x:xs) = x + sum' xs
    @@ -335,7 +335,7 @@ be a catch-all pattern at the end
    * The **as pattern** is used to reference the "whole thing": Put a name followed by `@`
    in front of the pattern:

    ```
    ```haskell
    capital :: String -> String
    capital "" = "Empty string, whoops!"
    capital all@(x:xs) = "The first letter of " ++ all ++ " is " ++ [x]
    @@ -344,7 +344,7 @@ in front of the pattern:
    * **Guards** are similar to if statements and check for boolean conditions. There's no `=`
    after the function name:

    ```
    ```haskell
    bmiTell :: (RealFloat a) => a -> String
    bmiTell bmi
    | bmi <= 18.5 = "You're underweight, you emo, you!"
    @@ -358,7 +358,7 @@ evaluation falls through to the next pattern

    * Guards can have as many parameters as we want

    ```
    ```haskell
    bmiTell :: (RealFloat a) => a -> a -> String
    bmiTell weight height
    | weight / height ^ 2 <= 18.5 = "You're underweight, you emo, you!"
    @@ -367,14 +367,14 @@ evaluation falls through to the next pattern
    | otherwise = "You're a whale, congratulations!"
    ```

    ```
    ```haskell
    max' :: (Ord a) => a -> a -> a
    max' a b
    | a > b = a
    | otherwise = b
    ```

    ```
    ```haskell
    myCompare :: (Ord a) => a -> a -> Ordering
    a `myCompare` b
    | a > b = GT
    @@ -385,7 +385,7 @@ evaluation falls through to the next pattern
    * Guards can use a **where** block to define functions that are only visible inside the
    guard function

    ```
    ```haskell
    bmiTell :: (RealFloat a) => a -> a -> String
    bmiTell weight height
    | bmi <= skinny = "You're underweight, you emo, you!"
    @@ -400,30 +400,30 @@ guard function

    * Combined with a patteren match

    ```
    ```haskell
    ...
    where bmi = weight / height ^ 2
    (skinny, normal, fat) = (18.5, 25.0, 30.0)
    ```

    * More Examples

    ```
    ```haskell
    initials :: String -> String -> String
    initials firstname lastname = [f] ++ ". " ++ [l] ++ "."
    where (f:_) = firstname
    (l:_) = lastname
    ```

    ```
    ```haskell
    calcBmis :: (RealFloat a) => [(a, a)] -> [a]
    calcBmis xs = [bmi w h | (w, h) <- xs]
    where bmi weight height = weight / height ^ 2
    ```

    * **Let bindings** are similar to where bindings. Their form is `let <bindings> in <expression>`.

    ```
    ```haskell
    cylinder :: (RealFloat a) => a -> a -> a
    cylinder r h =
    let sideArea = 2 * pi * r * h
    @@ -434,61 +434,61 @@ guard function
    * The difference between let bindings and where bindings is that let bindings are
    expressions, just like if statements:

    ```
    ```haskell
    4 * (if 10 > 5 then 10 else 0) + 2 (42)
    ```

    ```
    ```haskell
    4 * (let a = 9 in a + 1) + 2 (42)
    ```

    * Let bindings can be used to introduce functions in a local scope

    ```
    ```haskell
    [let square x = x * x in (square 5, square 3, square 2)] ( [(25,9,4)] )
    ```

    * To let bind several variables they get separated by a semicolon

    ```
    ```haskell
    (let a = 100; b = 200; c = 300 in a*b*c, let foo="Hey "; bar = "there!" in foo ++ bar)
    ```

    * Let bindings can be used with pattern matching

    ```
    ```haskell
    (let (a,b,c) = (1,2,3) in a+b+c) * 100 (600)
    ```

    * Let bindings can be used in list comprehensions

    ```
    ```haskell
    calcBmis :: (RealFloat a) => [(a, a)] -> [a]
    calcBmis xs = [bmi | (w, h) <- xs, let bmi = w / h ^ 2]
    ```

    * Predicates come after the let binding

    ```
    ```haskell
    calcBmis :: (RealFloat a) => [(a, a)] -> [a]
    calcBmis xs = [bmi | (w, h) <- xs, let bmi = w / h ^ 2, bmi >= 25.0]
    ```

    * **Case expressions** are very similar to pattern matching:

    ```
    ```haskell
    head' :: [a] -> a
    head' [] = error "No head for empty lists!"
    head' (x:_) = x
    ```

    ```
    ```haskell
    head' :: [a] -> a
    head' xs = case xs of [] -> error "No head for empty lists!"
    (x:_) -> x
    ```

    ```
    ```haskell
    case expression of pattern -> result
    pattern -> result
    pattern -> result
    @@ -498,7 +498,7 @@ expressions, just like if statements:
    * Pattern matching can only be used with function definitions. Cases expressions
    work everywhere

    ```
    ```haskell
    describeList :: [a] -> String
    describeList xs = "The list is " ++ case xs of [] -> "empty."
    [x] -> "a singleton list."
    @@ -511,7 +511,7 @@ work everywhere

    * Try to start with the edge cases

    ```
    ```haskell
    maximum' :: (Ord a) => [a] -> a
    maximum' [] = error "maximum of empty list"
    maximum' [x] = x
    @@ -521,47 +521,47 @@ work everywhere
    where maxTail = maximum' xs
    ```

    ```
    ```haskell
    maximum' :: (Ord a) => [a] -> a
    maximum' [] = error "maximum of empty list"
    maximum' [x] = x
    maximum' (x:xs) = max x (maximum' xs)
    ```

    ```
    ```haskell
    replicate' :: (Num i, Ord i) => i -> a -> [a]
    replicate' n x
    | n <= 0 = []
    | otherwhise = x:replicate' (n-1) x
    ```

    ```
    ```haskell
    take' :: (Num i, Ord i) => i -> [a] -> [a]
    take' n _
    | n <= 0 = []
    take' _ [] = []
    take' n (x:xs) = x : take' (n-1) xs
    ```

    ```
    ```haskell
    reverse' :: [a] -> [a]
    reverse' [] = []
    reverse' (x:xs) = reverse' xs ++ [x]
    ```

    ```
    ```haskell
    repeat' :: a -> [a]
    repeat' x = x:repeat' x
    ```

    ```
    ```haskell
    zip' :: [a] -> [b] -> [(a,b)]
    zip' _ [] = []
    zip' [] _ = []
    zip' (x:xs) (y:ys) = (x,y):zip' xs ys
    ```

    ```
    ```haskell
    elem' :: (Eq a) => a -> [a] -> Bool
    elem' a [] = False
    elem' a (x:xs)
    @@ -575,7 +575,7 @@ work everywhere
    > list in front (and those values are sorted), then comes the head of the list in the middle
    > and then come all the values that are bigger than the head (they're also sorted)
    ```
    ```haskell
    quicksort :: (Ord a) => [a] -> [a]
    quicksort [] = []
    quicksort (x:xs) =
    @@ -598,7 +598,7 @@ than one argument: Calling `max 4 5` creates a function which takes *one* argume
    returns `4` if the argument is smaller and the argument itself if it is bigger than `4`.
    These calls are equivalent:

    ```
    ```haskell
    max 4 5
    (max 4) 5
    ```
  18. @mikehaertl mikehaertl revised this gist Aug 4, 2012. 1 changed file with 3 additions and 3 deletions.
    6 changes: 3 additions & 3 deletions gistfile1.md
    Original file line number Diff line number Diff line change
    @@ -74,9 +74,9 @@ doubleUs x y = x*2 + y*2
    * `if` have a `then` and always require a `else`

    ```haskell
    doubleSmallNumber x = if x > 100
    then x
    else x*2
    doubleSmallNumber x = if x > 100
    then x
    else x*2
    ```

    * `if` is also an expression
  19. @mikehaertl mikehaertl revised this gist Aug 4, 2012. 1 changed file with 3 additions and 3 deletions.
    6 changes: 3 additions & 3 deletions gistfile1.md
    Original file line number Diff line number Diff line change
    @@ -74,9 +74,9 @@ doubleUs x y = x*2 + y*2
    * `if` have a `then` and always require a `else`

    ```haskell
    doubleSmallNumber x = if x > 100
    then x
    else x*2
    doubleSmallNumber x = if x > 100
    then x
    else x*2
    ```

    * `if` is also an expression
  20. @mikehaertl mikehaertl revised this gist Aug 4, 2012. 1 changed file with 16 additions and 16 deletions.
    32 changes: 16 additions & 16 deletions gistfile1.md
    Original file line number Diff line number Diff line change
    @@ -26,7 +26,7 @@ l: myfunctions.hs
    * Interactive GHC is started with `ghci`
    * Simple arithmetic:

    ```
    ```haskell
    2 + 15
    49 * 100
    1892 - 1472
    @@ -37,13 +37,13 @@ l: myfunctions.hs

    * Surround negative numbers with brackets:

    ```
    ```haskell
    5 * (-3)
    ```

    * Boolean algebra with `True`, `False`, `not`, `&&`and `||`

    ```
    ```haskell
    not (True && True)
    ```

    @@ -59,21 +59,21 @@ not (True && True)

    * Prefix functions can be written as infix with backticks:

    ```
    ```haskell
    div 92 10
    92 `div` 10
    ```

    * Functions are defined with `=`

    ```
    ```haskell
    doubleMe x = x + x
    doubleUs x y = x*2 + y*2
    ```

    * `if` have a `then` and always require a `else`

    ```
    ```haskell
    doubleSmallNumber x = if x > 100
    then x
    else x*2
    @@ -83,30 +83,30 @@ doubleSmallNumber x = if x > 100

    * **Lists** are collections of homogenous elements: all elements have the same type

    ```
    ```haskell
    lostNumbers = [4,8,15,16,23,42]
    someString = "Some string"
    ```

    * Use `++` to put two lists together (goes through the complete list!)

    ```
    [1,2,3,4] ++ [6,7,8]
    "Hello" ++ " " ++ "world"
    ```haskell
    [1,2,3,4] ++ [6,7,8]
    "Hello" ++ " " ++ "world"
    ```

    * Use `:` to prepend LHS to RHS list

    ```
    'A':" SMALL CAT"
    1:[2,3,4,5]
    1:2:3:[]
    ```haskell
    'A':" SMALL CAT"
    1:[2,3,4,5]
    1:2:3:[]
    ```

    * Use `!!` to get an element by index (0 based, index must exist)

    ```
    "Steve Buscemi" !! 6
    ```haskell
    "Steve Buscemi" !! 6
    ```

    * Use `<`, `<=`, `>` and `>=` to lexographically compare lists
  21. @mikehaertl mikehaertl revised this gist Aug 4, 2012. 1 changed file with 20 additions and 20 deletions.
    40 changes: 20 additions & 20 deletions gistfile1.md
    Original file line number Diff line number Diff line change
    @@ -15,8 +15,8 @@ This is a summary of the "Learn You A Haskell" online book under http://learnyou
    * GHC is the most widely used Haskell compiler
    * To load a file you do:

    ```haskell
    l: myfunctions.hs
    ```haskell
    l: myfunctions.hs
    ```

    ***
    @@ -26,7 +26,7 @@ This is a summary of the "Learn You A Haskell" online book under http://learnyou
    * Interactive GHC is started with `ghci`
    * Simple arithmetic:

    ```
    ```
    2 + 15
    49 * 100
    1892 - 1472
    @@ -37,14 +37,14 @@ This is a summary of the "Learn You A Haskell" online book under http://learnyou

    * Surround negative numbers with brackets:

    ```
    5 * (-3)
    ```
    5 * (-3)
    ```

    * Boolean algebra with `True`, `False`, `not`, `&&`and `||`

    ```
    not (True && True)
    ```
    not (True && True)
    ```

    * Test for equality with `==` and inequality with `/=`
    @@ -59,33 +59,33 @@ This is a summary of the "Learn You A Haskell" online book under http://learnyou

    * Prefix functions can be written as infix with backticks:

    ```
    div 92 10
    92 `div` 10
    ```
    div 92 10
    92 `div` 10
    ```

    * Functions are defined with `=`

    ```
    doubleMe x = x + x
    doubleUs x y = x*2 + y*2
    ```
    doubleMe x = x + x
    doubleUs x y = x*2 + y*2
    ```

    * `if` have a `then` and always require a `else`

    ```
    doubleSmallNumber x = if x > 100
    then x
    else x*2
    ```
    doubleSmallNumber x = if x > 100
    then x
    else x*2
    ```

    * `if` is also an expression

    * **Lists** are collections of homogenous elements: all elements have the same type

    ```
    lostNumbers = [4,8,15,16,23,42]
    someString = "Some string"
    ```
    lostNumbers = [4,8,15,16,23,42]
    someString = "Some string"
    ```

    * Use `++` to put two lists together (goes through the complete list!)
  22. @mikehaertl mikehaertl revised this gist Aug 4, 2012. 1 changed file with 36 additions and 19 deletions.
    55 changes: 36 additions & 19 deletions gistfile1.md
    Original file line number Diff line number Diff line change
    @@ -27,12 +27,12 @@ This is a summary of the "Learn You A Haskell" online book under http://learnyou
    * Simple arithmetic:

    ```
    2 + 15
    49 * 100
    1892 - 1472
    5 / 2
    50 * 100 - 4999
    50 * (100 - 4999)
    2 + 15
    49 * 100
    1892 - 1472
    5 / 2
    50 * 100 - 4999
    50 * (100 - 4999)
    ```

    * Surround negative numbers with brackets:
    @@ -217,7 +217,8 @@ This is a summary of the "Learn You A Haskell" online book under http://learnyou
    :t (True, 'a') ( (True,'a') :: (Bool, Char) )
    ```

    * All functions should use a **type declaration** with `::` ("has type of"). Multiple arguments are also separeted with `->` just like the type declaration itself.
    * All functions should use a **type declaration** with `::` ("has type of").
    Multiple arguments are also separeted with `->` just like the type declaration itself.

    ```
    removeUppercase :: [Char] -> [Char]
    @@ -237,14 +238,17 @@ This is a summary of the "Learn You A Haskell" online book under http://learnyou
    - Tuples, as mentioned in chapter 2
    - `Ordering` : Can be `GT`, `LT` or `EQ`

    * **Type variables** can be used in function declarations. They stand for a type. Without a class constraint they mean "any type"
    * **Type variables** can be used in function declarations. They stand for a type.
    Without a class constraint they mean "any type"

    ```
    :t head (head :: [a] -> a)
    :t fst (fst :: (a, b) -> a)
    ```

    * **Typeclasses** are like interfaces for types. If a type is part of a typeclass it implements that class' behavior. The `=>` symbol separates the *class constraint* from the declaration:
    * **Typeclasses** are like interfaces for types. If a type is part of a typeclass
    it implements that class' behavior. The `=>` symbol separates the **class constraint**
    from the declaration:

    ```
    :t (==) ( (==) :: (Eq a) => a -> a -> Bool )
    @@ -281,7 +285,9 @@ This is a summary of the "Learn You A Haskell" online book under http://learnyou

    # 4. Syntax in Functions

    * Functions can be defined with **pattern matching**. Patterns make sure that the input matches a specified pattern. The first matching pattern is executed. There should always be a catch-all pattern at the end
    * Functions can be defined with **pattern matching**. Patterns make sure that the input
    matches a specified pattern. The first matching pattern is executed. There should always
    be a catch-all pattern at the end

    ```
    lucky :: (Integral a) => a -> String
    @@ -326,15 +332,17 @@ This is a summary of the "Learn You A Haskell" online book under http://learnyou
    sum' (x:xs) = x + sum' xs
    ```

    * The **as pattern** is used to reference the "whole thing": Put a name followed by `@` in front of the pattern:
    * The **as pattern** is used to reference the "whole thing": Put a name followed by `@`
    in front of the pattern:

    ```
    capital :: String -> String
    capital "" = "Empty string, whoops!"
    capital all@(x:xs) = "The first letter of " ++ all ++ " is " ++ [x]
    ```

    * **Guards** are similar to if statements and check for boolean conditions. There's no `=` after the function name:
    * **Guards** are similar to if statements and check for boolean conditions. There's no `=`
    after the function name:

    ```
    bmiTell :: (RealFloat a) => a -> String
    @@ -345,7 +353,8 @@ This is a summary of the "Learn You A Haskell" online book under http://learnyou
    | otherwise = "You're a whale, congratulations!"
    ```

    * Guards can be combined with patterns: If all guards of a function evaluate to `False`, evaluation falls through to the next pattern
    * Guards can be combined with patterns: If all guards of a function evaluate to `False`,
    evaluation falls through to the next pattern

    * Guards can have as many parameters as we want

    @@ -373,7 +382,8 @@ This is a summary of the "Learn You A Haskell" online book under http://learnyou
    | otherwise = LT
    ```

    * Guards can use a **where** block to define functions that are only visible inside the guard function
    * Guards can use a **where** block to define functions that are only visible inside the
    guard function

    ```
    bmiTell :: (RealFloat a) => a -> a -> String
    @@ -421,7 +431,8 @@ This is a summary of the "Learn You A Haskell" online book under http://learnyou
    in sideArea + 2 * topArea
    ```

    * The difference between let bindings and where bindings is that let bindings are expressions, just like if statements:
    * The difference between let bindings and where bindings is that let bindings are
    expressions, just like if statements:

    ```
    4 * (if 10 > 5 then 10 else 0) + 2 (42)
    @@ -484,7 +495,8 @@ This is a summary of the "Learn You A Haskell" online book under http://learnyou
    ...
    ```

    * Pattern matching can only be used with function definitions. Cases expressions work everywhere
    * Pattern matching can only be used with function definitions. Cases expressions
    work everywhere

    ```
    describeList :: [a] -> String
    @@ -572,14 +584,19 @@ This is a summary of the "Learn You A Haskell" online book under http://learnyou
    in smallerSorted ++ [x] ++ biggerSorted
    ```

    ***

    # 5. Higher order functions
    # 6. Higher order functions

    * **Higher order functions** take other functions as parameters and return functions themselves (which is what makes up the ultimate *haskell experience*)
    * **Higher order functions** take other functions as parameters and return functions
    themselves (which is what makes up the ultimate *haskell experience*)

    * Functions in haskell only take *one* argument

    * **Curried functions** are used to give the impression that a function can have more than one argument: Calling `max 4 5` creates a function which takes *one* argument and returns `4` if the argument is smaller and the argument itself if it is bigger than `4`. These calls are equivalent:
    * **Curried functions** are used to give the impression that a function can have more
    than one argument: Calling `max 4 5` creates a function which takes *one* argument and
    returns `4` if the argument is smaller and the argument itself if it is bigger than `4`.
    These calls are equivalent:

    ```
    max 4 5
  23. @mikehaertl mikehaertl revised this gist Aug 4, 2012. 1 changed file with 35 additions and 19 deletions.
    54 changes: 35 additions & 19 deletions gistfile1.md
    Original file line number Diff line number Diff line change
    @@ -3,6 +3,8 @@ Learn you a Haskell - In a nutshell

    This is a summary of the "Learn You A Haskell" online book under http://learnyouahaskell.com/chapters.

    ***

    # 1. Introduction

    * Haskell is a functional programming language.
    @@ -17,6 +19,8 @@ This is a summary of the "Learn You A Haskell" online book under http://learnyou
    l: myfunctions.hs
    ```

    ***

    # 2. Starting Out

    * Interactive GHC is started with `ghci`
    @@ -77,7 +81,7 @@ This is a summary of the "Learn You A Haskell" online book under http://learnyou

    * `if` is also an expression

    * *Lists* are homogenous collections: all elements have the same type
    * **Lists** are collections of homogenous elements: all elements have the same type

    ```
    lostNumbers = [4,8,15,16,23,42]
    @@ -142,13 +146,13 @@ This is a summary of the "Learn You A Haskell" online book under http://learnyou
    - `take 10 (repeat 5)` : repeat the element (`[5,5,5,5,5,5,5,5,5,5]`)
    - `replicate 3 10` : repeat the element a number of times (`[10,10,10]`)

    * *List comprehensions* are similar to mathematical equations
    * **List comprehensions** are similar to mathematical equations

    ```
    [x*2 | x <- [1..5]] ([2,4,6,8,10])
    ```

    * *Predicates* are conditions for list comprehensions
    * **Predicates** are conditions for list comprehensions

    ```
    [x*2 | x <- [1..5], x*2 >= 5] ([6,8,10])
    @@ -185,7 +189,7 @@ This is a summary of the "Learn You A Haskell" online book under http://learnyou
    [ [x | x <- xs, even x] | xs <- xxs] ([[2],[2,4],[4]]
    ```

    * *Tuples* can contain several types, but for the type of two Tuples to be the same, the number and types of their elements must match
    * **Tuples** can contain several types, but for the type of two Tuples to be the same, the number and types of their elements must match

    ```
    (1,2)
    @@ -199,10 +203,11 @@ This is a summary of the "Learn You A Haskell" online book under http://learnyou
    - `snd (9,"Hey")` : returns second component of a pair (`"Hey"`)
    - `zip [1..3] ['a'..'c']` : combine two lists to a list of tuples ( `[(1,'a'), (2,'b'), (3,'c')]` )

    ***

    # 3. Types and Typeclasses

    * *Types* always start with an uppercase letter
    * **Types** always start with an uppercase letter

    * Use `:t` to get a type of something

    @@ -212,7 +217,7 @@ This is a summary of the "Learn You A Haskell" online book under http://learnyou
    :t (True, 'a') ( (True,'a') :: (Bool, Char) )
    ```

    * All functions should use a *type declaration* with `::` ("has type of"). Multiple arguments are also separeted with `->` just like the type declaration itself.
    * All functions should use a **type declaration** with `::` ("has type of"). Multiple arguments are also separeted with `->` just like the type declaration itself.

    ```
    removeUppercase :: [Char] -> [Char]
    @@ -232,14 +237,14 @@ This is a summary of the "Learn You A Haskell" online book under http://learnyou
    - Tuples, as mentioned in chapter 2
    - `Ordering` : Can be `GT`, `LT` or `EQ`

    * *Type variables* can be used in function declarations. They stand for a type. Without a class constraint they mean "any type"
    * **Type variables** can be used in function declarations. They stand for a type. Without a class constraint they mean "any type"

    ```
    :t head (head :: [a] -> a)
    :t fst (fst :: (a, b) -> a)
    ```

    * *Typeclasses* are like interfaces for types. If a type is part of a typeclass it implements that class' behavior. The `=>` symbol separates the *class constraint* from the declaration:
    * **Typeclasses** are like interfaces for types. If a type is part of a typeclass it implements that class' behavior. The `=>` symbol separates the *class constraint* from the declaration:

    ```
    :t (==) ( (==) :: (Eq a) => a -> a -> Bool )
    @@ -272,10 +277,11 @@ This is a summary of the "Learn You A Haskell" online book under http://learnyou
    (read "5" :: Float) * 4
    ```

    ***

    # 3. Syntax in Functions
    # 4. Syntax in Functions

    * Functions can be defined with *pattern matching*. Patterns make sure that the input matches a specified pattern. The first matching pattern is executed. There should always be a catch-all pattern at the end
    * Functions can be defined with **pattern matching**. Patterns make sure that the input matches a specified pattern. The first matching pattern is executed. There should always be a catch-all pattern at the end

    ```
    lucky :: (Integral a) => a -> String
    @@ -320,15 +326,15 @@ This is a summary of the "Learn You A Haskell" online book under http://learnyou
    sum' (x:xs) = x + sum' xs
    ```

    * The *as pattern* is used to reference the "whole thing": Put a name followed by `@` in front of the pattern:
    * The **as pattern** is used to reference the "whole thing": Put a name followed by `@` in front of the pattern:

    ```
    capital :: String -> String
    capital "" = "Empty string, whoops!"
    capital all@(x:xs) = "The first letter of " ++ all ++ " is " ++ [x]
    ```

    * *Guards* are similar to if statements and check for boolean conditions. There's no `=` after the function name:
    * **Guards** are similar to if statements and check for boolean conditions. There's no `=` after the function name:

    ```
    bmiTell :: (RealFloat a) => a -> String
    @@ -367,7 +373,7 @@ This is a summary of the "Learn You A Haskell" online book under http://learnyou
    | otherwise = LT
    ```

    * Guards can use a `where` block to define functions that are only visible inside the guard function
    * Guards can use a **where** block to define functions that are only visible inside the guard function

    ```
    bmiTell :: (RealFloat a) => a -> a -> String
    @@ -405,7 +411,7 @@ This is a summary of the "Learn You A Haskell" online book under http://learnyou
    where bmi weight height = weight / height ^ 2
    ```

    * *Let bindings* are similar to where bindings. Their form is `let <bindings> in <expression>`.
    * **Let bindings** are similar to where bindings. Their form is `let <bindings> in <expression>`.

    ```
    cylinder :: (RealFloat a) => a -> a -> a
    @@ -457,7 +463,7 @@ This is a summary of the "Learn You A Haskell" online book under http://learnyou
    calcBmis xs = [bmi | (w, h) <- xs, let bmi = w / h ^ 2, bmi >= 25.0]
    ```

    * *Case expressions* are very similar to pattern matching:
    * **Case expressions** are very similar to pattern matching:

    ```
    head' :: [a] -> a
    @@ -487,8 +493,9 @@ This is a summary of the "Learn You A Haskell" online book under http://learnyou
    xs -> "a longer list."
    ```

    ***

    # 4. Recursion
    # 5. Recursion

    * Try to start with the edge cases

    @@ -550,7 +557,11 @@ This is a summary of the "Learn You A Haskell" online book under http://learnyou
    | otherwise = a `elem'` xs
    ```

    * Quicksort can be implemented very elegantly. The main algorithm is "a sorted list is a list that has all the values smaller than (or equal to) the head of the list in front (and those values are sorted), then comes the head of the list in the middle and then come all the values that are bigger than the head (they're also sorted)"
    * Quicksort can be implemented very elegantly. The main algorithm is

    > A sorted list is a list that has all the values smaller than (or equal to) the head of the
    > list in front (and those values are sorted), then comes the head of the list in the middle
    > and then come all the values that are bigger than the head (they're also sorted)
    ```
    quicksort :: (Ord a) => [a] -> [a]
    @@ -564,8 +575,13 @@ This is a summary of the "Learn You A Haskell" online book under http://learnyou

    # 5. Higher order functions

    * Higher order functions take other functions as parameters and return functions themselves (which is what makes up the ultimate *haskell experience*)
    * **Higher order functions** take other functions as parameters and return functions themselves (which is what makes up the ultimate *haskell experience*)

    * Functions in haskell only take *one* argument

    * *Curried functions*
    * **Curried functions** are used to give the impression that a function can have more than one argument: Calling `max 4 5` creates a function which takes *one* argument and returns `4` if the argument is smaller and the argument itself if it is bigger than `4`. These calls are equivalent:

    ```
    max 4 5
    (max 4) 5
    ```
  24. @mikehaertl mikehaertl revised this gist Aug 4, 2012. 1 changed file with 11 additions and 5 deletions.
    16 changes: 11 additions & 5 deletions gistfile1.md
    Original file line number Diff line number Diff line change
    @@ -1,5 +1,5 @@
    Haskell Overview
    ----------------
    Learn you a Haskell - In a nutshell
    -----------------------------------

    This is a summary of the "Learn You A Haskell" online book under http://learnyouahaskell.com/chapters.

    @@ -44,8 +44,8 @@ This is a summary of the "Learn You A Haskell" online book under http://learnyou
    ```

    * Test for equality with `==` and inequality with `/=`
    * *infix* functions like `*` stand between the operators
    * Most functions are *prefix* functions:
    * **infix** functions like `*` stand between the operators
    * Most functions are **prefix** functions:

    - `succ 8` : successor (`9`)
    - `min 3 4` : minimum of 2 values (`3`)
    @@ -562,4 +562,10 @@ This is a summary of the "Learn You A Haskell" online book under http://learnyou
    ```


    # 5. Higher order functions
    # 5. Higher order functions

    * Higher order functions take other functions as parameters and return functions themselves (which is what makes up the ultimate *haskell experience*)

    * Functions in haskell only take *one* argument

    * *Curried functions*
  25. @mikehaertl mikehaertl revised this gist Aug 4, 2012. 1 changed file with 3 additions and 1 deletion.
    4 changes: 3 additions & 1 deletion gistfile1.md
    Original file line number Diff line number Diff line change
    @@ -13,7 +13,7 @@ This is a summary of the "Learn You A Haskell" online book under http://learnyou
    * GHC is the most widely used Haskell compiler
    * To load a file you do:

    ```
    ```haskell
    l: myfunctions.hs
    ```

    @@ -22,12 +22,14 @@ This is a summary of the "Learn You A Haskell" online book under http://learnyou
    * Interactive GHC is started with `ghci`
    * Simple arithmetic:

    ```
    2 + 15
    49 * 100
    1892 - 1472
    5 / 2
    50 * 100 - 4999
    50 * (100 - 4999)
    ```

    * Surround negative numbers with brackets:

  26. @mikehaertl mikehaertl revised this gist Aug 4, 2012. 1 changed file with 1 addition and 3 deletions.
    4 changes: 1 addition & 3 deletions gistfile1.md
    Original file line number Diff line number Diff line change
    @@ -22,14 +22,12 @@ This is a summary of the "Learn You A Haskell" online book under http://learnyou
    * Interactive GHC is started with `ghci`
    * Simple arithmetic:

    ```
    2 + 15
    49 * 100
    1892 - 1472
    5 / 2
    50 * 100 - 4999
    50 * (100 - 4999)
    ```

    * Surround negative numbers with brackets:

    @@ -137,7 +135,7 @@ This is a summary of the "Learn You A Haskell" online book under http://learnyou
    - `minimum [5,4,3,2,1]` : minimum of orderable list (`1`)
    - `sum [5,4,3]` : sum of number list (`12`)
    - `product [5,4,3]` : product of number list (`60`)
    - `4 \`elem\` [5,4,3]` : wether element is in list, usually infixed (`True`)
    - ``4 `elem` [5,4,3]`` : wether element is in list, usually infixed (`True`)
    - `take 10 (cycle [1,2,3])` : repeat the list elements (`[1,2,3,1,2,3,1,2,3,1]`)
    - `take 10 (repeat 5)` : repeat the element (`[5,5,5,5,5,5,5,5,5,5]`)
    - `replicate 3 10` : repeat the element a number of times (`[10,10,10]`)
  27. @mikehaertl mikehaertl revised this gist Aug 4, 2012. 1 changed file with 66 additions and 65 deletions.
    131 changes: 66 additions & 65 deletions gistfile1.md
    Original file line number Diff line number Diff line change
    @@ -9,12 +9,13 @@ This is a summary of the "Learn You A Haskell" online book under http://learnyou
    * "what it is" over "what to do"
    * Haskell is *lazy* - no calculation until a result is used
    * Statically typed - errors are caught on compile time
    * Type inference - it auto-detects the right type e.g. for a = 5 + 4
    * Type inference - it auto-detects the right type e.g. for `a = 5 + 4`
    * GHC is the most widely used Haskell compiler
    * To load a file you do:

    ```
    l: myfunctions.hs

    ```

    # 2. Starting Out

    @@ -46,11 +47,11 @@ This is a summary of the "Learn You A Haskell" online book under http://learnyou
    * *infix* functions like `*` stand between the operators
    * Most functions are *prefix* functions:

    - succ 8 : successor (9)
    - min 3 4 : minimum of 2 values (3)
    - max 4 5 : maximum of 2 values (5)
    - div 13 6 : integral division of 2 integers (2)
    - odd 5 : wether number is odd (True)
    - `succ 8` : successor (`9`)
    - `min 3 4` : minimum of 2 values (`3`)
    - `max 4 5` : maximum of 2 values (`5`)
    - `div 13 6` : integral division of 2 integers (`2`)
    - `odd 5` : wether number is odd (`True`)

    * Prefix functions can be written as infix with backticks:

    @@ -76,7 +77,7 @@ This is a summary of the "Learn You A Haskell" online book under http://learnyou

    * `if` is also an expression

    * Lists are *homogenous* (all elements have the same type):
    * *Lists* are homogenous collections: all elements have the same type

    ```
    lostNumbers = [4,8,15,16,23,42]
    @@ -90,7 +91,7 @@ This is a summary of the "Learn You A Haskell" online book under http://learnyou
    "Hello" ++ " " ++ "world"
    ```

    * Use `:` to prepend LHS to RHS
    * Use `:` to prepend LHS to RHS list

    ```
    'A':" SMALL CAT"
    @@ -123,25 +124,25 @@ This is a summary of the "Learn You A Haskell" online book under http://learnyou

    * List methods

    - head [5,4,3] : first element of a list (5)
    - tail [5,4,3] : tail without head ([4,3])
    - last [5,4,3] : last element of a list (3)
    - init [5,4,3] : list without tail ([5,4])
    - length [5,4,3] : number of elements (3)
    - null [5,4,3] : wether list is empty (False)
    - reverse [5,4,3] : reverse list ([3,4,5])
    - take 3 [5,4,3,2,1] : extract number of elements from list start ([5,4,3])
    - drop 3 [5,4,3,2,1] : drop first elements of a list ([2,1])
    - maximum [5,4,3,2,1] : maximum of orderable list (5)
    - minimum [5,4,3,2,1] : minimum of orderable list (1)
    - sum [5,4,3] : sum of number list (12)
    - product [5,4,3] : product of number list (60)
    - 4 `elem` [5,4,3] : wether element is in list, usually infixed (True)
    - take 10 (cycle [1,2,3]) : repeat the list elements ([1,2,3,1,2,3,1,2,3,1])
    - take 10 (repeat 5) : repeat the element ([5,5,5,5,5,5,5,5,5,5])
    - replicate 3 10 : repeat the element a number of times ([10,10,10])

    * List comprehensions are similar to mathematical equations
    - `head [5,4,3]` : first element of a list (`5`)
    - `tail [5,4,3]` : tail without head (`[4,3]`)
    - `last [5,4,3]` : last element of a list (`3`)
    - `init [5,4,3]` : list without tail (`[5,4]`)
    - `length [5,4,3]` : number of elements (`3`)
    - `null [5,4,3]` : wether list is empty (`False`)
    - `reverse [5,4,3]` : reverse list (`[3,4,5]`)
    - `take 3 [5,4,3,2,1]` : extract number of elements from list start (`[5,4,3]`)
    - `drop 3 [5,4,3,2,1]` : drop first elements of a list (`[2,1]`)
    - `maximum [5,4,3,2,1]` : maximum of orderable list (`5`)
    - `minimum [5,4,3,2,1]` : minimum of orderable list (`1`)
    - `sum [5,4,3]` : sum of number list (`12`)
    - `product [5,4,3]` : product of number list (`60`)
    - `4 \`elem\` [5,4,3]` : wether element is in list, usually infixed (`True`)
    - `take 10 (cycle [1,2,3])` : repeat the list elements (`[1,2,3,1,2,3,1,2,3,1]`)
    - `take 10 (repeat 5)` : repeat the element (`[5,5,5,5,5,5,5,5,5,5]`)
    - `replicate 3 10` : repeat the element a number of times (`[10,10,10]`)

    * *List comprehensions* are similar to mathematical equations

    ```
    [x*2 | x <- [1..5]] ([2,4,6,8,10])
    @@ -153,7 +154,7 @@ This is a summary of the "Learn You A Haskell" online book under http://learnyou
    [x*2 | x <- [1..5], x*2 >= 5] ([6,8,10])
    ```

    * There can be more predicates
    * There can be more than one predicates

    ```
    [ x | x <- [10..20], x /= 10, x /= 15, x /= 19]
    @@ -184,7 +185,7 @@ This is a summary of the "Learn You A Haskell" online book under http://learnyou
    [ [x | x <- xs, even x] | xs <- xxs] ([[2],[2,4],[4]]
    ```

    * Tuples can contain several types, but for the type of two Tuples to be the same, the number and types of their elements must match
    * *Tuples* can contain several types, but for the type of two Tuples to be the same, the number and types of their elements must match

    ```
    (1,2)
    @@ -194,14 +195,14 @@ This is a summary of the "Learn You A Haskell" online book under http://learnyou

    * Tuple functions

    - fst (8,11) : returns first component of a pair (8)
    - snd (9,"Hey") : returns second component of a pair ("Hey")
    - zip [1..3] ['a'..'c'] : combine two lists to a list of tuples ( [(1,'a'), (2,'b'), (3,'c')] )
    - `fst (8,11)` : returns first component of a pair (`8`)
    - `snd (9,"Hey")` : returns second component of a pair (`"Hey"`)
    - `zip [1..3] ['a'..'c']` : combine two lists to a list of tuples ( `[(1,'a'), (2,'b'), (3,'c')]` )


    # 3. Types and Typeclasses

    * Types always start with an uppercase letter
    * *Types* always start with an uppercase letter

    * Use `:t` to get a type of something

    @@ -211,7 +212,7 @@ This is a summary of the "Learn You A Haskell" online book under http://learnyou
    :t (True, 'a') ( (True,'a') :: (Bool, Char) )
    ```

    * All functions should use a type declaration with `::` ("has type of"). Multiple arguments are also separeted with `->` just like the type declaration itself.
    * All functions should use a *type declaration* with `::` ("has type of"). Multiple arguments are also separeted with `->` just like the type declaration itself.

    ```
    removeUppercase :: [Char] -> [Char]
    @@ -222,50 +223,50 @@ This is a summary of the "Learn You A Haskell" online book under http://learnyou

    * Common types

    - Int : Integer
    - Integer : Integer (big)
    - Float : Floating point
    - Double : Floating point with double precision
    - Bool : Boolean
    - Char : Character
    - `Int` : Integer
    - `Integer` : Integer (big)
    - `Float` : Floating point
    - `Double` : Floating point with double precision
    - `Bool` : Boolean
    - `Char` : Character
    - Tuples, as mentioned in chapter 2
    - Ordering : Can be `GT`, `LT` or `EQ`
    - `Ordering` : Can be `GT`, `LT` or `EQ`

    * Type variables can be used in function declarations. They mean "any type"
    * *Type variables* can be used in function declarations. They stand for a type. Without a class constraint they mean "any type"

    ```
    :t head (head :: [a] -> a)
    :t fst (fst :: (a, b) -> a)
    ```

    * Typeclasses are like interfaces for types. If a type is part of a typeclass it implements that class' behavior. The `=>` symbol separates the *class constraint* from the declaration:
    * *Typeclasses* are like interfaces for types. If a type is part of a typeclass it implements that class' behavior. The `=>` symbol separates the *class constraint* from the declaration:

    ```
    :t (==) ( (==) :: (Eq a) => a -> a -> Bool )
    ```

    - Eq : supports equality testing
    - Ord : can have ordering
    - Show : can be presented as string
    - Read : can be read from a string
    - Enum : ordered type which can be enumerated
    - Bounded : have an upper and lower bound
    - Num : can act like a number
    - Integral : can act like an integral number
    - Floating : can act like a floating point number
    - `Eq` : supports equality testing
    - `Ord` : can have ordering
    - `Show` : can be presented as string
    - `Read` : can be read from a string
    - `Enum` : ordered type which can be enumerated
    - `Bounded` : have an upper and lower bound
    - `Num` : can act like a number
    - `Integral` : can act like an integral number
    - `Floating` : can act like a floating point number

    * Related functions

    - 5 `compare` 3 : takes two `Ord` members of same type and returns a `Ordering` (GT)
    - show 3 : takes a `Show` and returns a `String` ("3")
    - read "True" : takes a `Read` and returns a `Read` (True)
    - succ LT : takes a `Enum` and returns next element (GT)
    - pred 'b' : takes a `Enum` and returns previous element ('a')
    - minBound :: Bool : takes a `Bounded` and returns lower bound (False)
    - maxBound :: Bool : takes a `Bounded` and returns lower bound (True)
    - fromIntegral 5 : takes a `Integral` and returns a `Num`
    - `5 \`compare\` 3` : takes two `Ord` members of same type and returns a `Ordering` (`GT`)
    - `show 3` : takes a `Show` and returns a `String` (`"3"`)
    - `read "True"` : takes a `Read` and returns a `Read` (`True`)
    - `succ LT` : takes a `Enum` and returns next element (`GT`)
    - `pred 'b'` : takes a `Enum` and returns previous element (`'a'`)
    - `minBound` :: Bool : takes a `Bounded` and returns lower bound (`False`)
    - `maxBound` :: Bool : takes a `Bounded` and returns lower bound (`True`)
    - `fromIntegral 5` : takes a `Integral` and returns a `Num`

    * Type annotations define the type of ambiguous expressions
    * *Type annotations* define the type of ambiguous expressions

    ```
    (read "5" :: Float) * 4
    @@ -274,7 +275,7 @@ This is a summary of the "Learn You A Haskell" online book under http://learnyou

    # 3. Syntax in Functions

    * Functions can be defined with *Pattern Matching*. Patterns make sure that the input matches a specified pattern. The first matching pattern is executed. There should always be a catch-all pattern at the end
    * Functions can be defined with *pattern matching*. Patterns make sure that the input matches a specified pattern. The first matching pattern is executed. There should always be a catch-all pattern at the end

    ```
    lucky :: (Integral a) => a -> String
    @@ -338,7 +339,7 @@ This is a summary of the "Learn You A Haskell" online book under http://learnyou
    | otherwise = "You're a whale, congratulations!"
    ```

    * Guards can be combined with patterns: If all guards of a function evaluate to False, evaluation falls through to the next pattern
    * Guards can be combined with patterns: If all guards of a function evaluate to `False`, evaluation falls through to the next pattern

    * Guards can have as many parameters as we want

    @@ -561,4 +562,4 @@ This is a summary of the "Learn You A Haskell" online book under http://learnyou
    ```


    # 5. Higher order functions
    # 5. Higher order functions
  28. @mikehaertl mikehaertl revised this gist Aug 4, 2012. 1 changed file with 124 additions and 0 deletions.
    124 changes: 124 additions & 0 deletions gistfile1.md
    Original file line number Diff line number Diff line change
    @@ -21,20 +21,26 @@ This is a summary of the "Learn You A Haskell" online book under http://learnyou
    * Interactive GHC is started with `ghci`
    * Simple arithmetic:

    ```
    2 + 15
    49 * 100
    1892 - 1472
    5 / 2
    50 * 100 - 4999
    50 * (100 - 4999)
    ```

    * Surround negative numbers with brackets:

    ```
    5 * (-3)
    ```

    * Boolean algebra with `True`, `False`, `not`, `&&`and `||`

    ```
    not (True && True)
    ```

    * Test for equality with `==` and inequality with `/=`
    * *infix* functions like `*` stand between the operators
    @@ -48,54 +54,72 @@ This is a summary of the "Learn You A Haskell" online book under http://learnyou

    * Prefix functions can be written as infix with backticks:

    ```
    div 92 10
    92 `div` 10
    ```

    * Functions are defined with `=`

    ```
    doubleMe x = x + x
    doubleUs x y = x*2 + y*2
    ```

    * `if` have a `then` and always require a `else`

    ```
    doubleSmallNumber x = if x > 100
    then x
    else x*2
    ```

    * `if` is also an expression

    * Lists are *homogenous* (all elements have the same type):

    ```
    lostNumbers = [4,8,15,16,23,42]
    someString = "Some string"
    ```

    * Use `++` to put two lists together (goes through the complete list!)

    ```
    [1,2,3,4] ++ [6,7,8]
    "Hello" ++ " " ++ "world"
    ```

    * Use `:` to prepend LHS to RHS

    ```
    'A':" SMALL CAT"
    1:[2,3,4,5]
    1:2:3:[]
    ```

    * Use `!!` to get an element by index (0 based, index must exist)

    ```
    "Steve Buscemi" !! 6
    ```

    * Use `<`, `<=`, `>` and `>=` to lexographically compare lists

    * List ranges are defined with `..`:

    ```
    [1..20]
    ['a'..'z']
    ```

    * Ranges can define a step size

    ```
    [2,4..20] ([2,4,6,8,10,12,16,18,20])
    [3,6..20] ([3,6,9,12,15,18])
    [20,19..15] ([20,19,18,17,16,15])
    ```

    * List methods

    @@ -119,38 +143,54 @@ This is a summary of the "Learn You A Haskell" online book under http://learnyou

    * List comprehensions are similar to mathematical equations

    ```
    [x*2 | x <- [1..5]] ([2,4,6,8,10])
    ```

    * *Predicates* are conditions for list comprehensions

    ```
    [x*2 | x <- [1..5], x*2 >= 5] ([6,8,10])
    ```

    * There can be more predicates

    ```
    [ x | x <- [10..20], x /= 10, x /= 15, x /= 19]
    ```

    * Comprehensions can be put inside a function

    ```
    boomBangs xs = [if x < 10 then "BOOM!" else "BANG!" | x <- xs, odd x]
    ```

    * Comprehensions can draw from several lists, which multiplies the lengths

    ```
    [ x*y | x <- [2,3], y <- [3,4,5]] ([6,8,10,9,12,15])
    ```

    * `_` is a dummy placeholder for a unused value

    ```
    length' xs = sum [1 | _ <- xs]
    ```

    * List comprehensions can be nested

    ```
    let xxs = [[1,2,3],[2,3,4],[4,5]]
    [ [x | x <- xs, even x] | xs <- xxs] ([[2],[2,4],[4]]
    ```

    * Tuples can contain several types, but for the type of two Tuples to be the same, the number and types of their elements must match

    ```
    (1,2)
    [(1,2), (3,2), (4,9)]
    [("Johnny", "Walker", 38), ("Kate", "Middleton", 27)]
    ```

    * Tuple functions

    @@ -165,16 +205,20 @@ This is a summary of the "Learn You A Haskell" online book under http://learnyou

    * Use `:t` to get a type of something

    ```
    :t 'a' ('a' :: Char)
    :t "HELLO" ("HELLO" :: [Char])
    :t (True, 'a') ( (True,'a') :: (Bool, Char) )
    ```

    * All functions should use a type declaration with `::` ("has type of"). Multiple arguments are also separeted with `->` just like the type declaration itself.

    ```
    removeUppercase :: [Char] -> [Char]
    removeUppercase :: String -> String (same as above)
    addThree :: Int -> Int -> Int -> Int
    addThree x y z = x + y + z
    ```

    * Common types

    @@ -189,12 +233,16 @@ This is a summary of the "Learn You A Haskell" online book under http://learnyou

    * Type variables can be used in function declarations. They mean "any type"

    ```
    :t head (head :: [a] -> a)
    :t fst (fst :: (a, b) -> a)
    ```

    * Typeclasses are like interfaces for types. If a type is part of a typeclass it implements that class' behavior. The `=>` symbol separates the *class constraint* from the declaration:

    ```
    :t (==) ( (==) :: (Eq a) => a -> a -> Bool )
    ```

    - Eq : supports equality testing
    - Ord : can have ordering
    @@ -219,81 +267,108 @@ This is a summary of the "Learn You A Haskell" online book under http://learnyou

    * Type annotations define the type of ambiguous expressions

    ```
    (read "5" :: Float) * 4
    ```


    # 3. Syntax in Functions

    * Functions can be defined with *Pattern Matching*. Patterns make sure that the input matches a specified pattern. The first matching pattern is executed. There should always be a catch-all pattern at the end

    ```
    lucky :: (Integral a) => a -> String
    lucky 7 = "LUCKY NUMBER SEVEN!"
    lucky x = "Sorry, you're out of luck, pal!"
    ```

    ```
    factorial :: (Integral a) => a -> a
    factorial 0 = 1
    factorial n = n * factorial (n - 1)
    ```

    ```
    addVectors :: (Num a) => (a, a) -> (a, a) -> (a, a)
    addVectors (x1, y1) (x2, y2) = (x1 + x2, y1 + y2)
    ```

    ```
    head' :: [a] -> a
    head' [] = error "Can't call head on an empty list, dummy!"
    head' (x:_) = x
    ```

    ```
    tell :: (Show a) => [a] -> String
    tell [] = "The list is empty"
    tell (x:[]) = "The list has one element: " ++ show x
    tell (x:y:[]) = "The list has two elements: " ++ show x ++ " and " ++ show y
    tell (x:y:_) = "This list is long. The first two elements are: " ++ show x ++ " and " ++ show y
    ```

    ```
    length' :: (Num b) => [a] -> b
    length' [] = 0
    length' (_:xs) = 1 + length' xs
    ```

    ```
    sum' :: (Num a) => [a] -> a
    sum' [] = 0
    sum' (x:xs) = x + sum' xs
    ```

    * The *as pattern* is used to reference the "whole thing": Put a name followed by `@` in front of the pattern:

    ```
    capital :: String -> String
    capital "" = "Empty string, whoops!"
    capital all@(x:xs) = "The first letter of " ++ all ++ " is " ++ [x]
    ```

    * *Guards* are similar to if statements and check for boolean conditions. There's no `=` after the function name:

    ```
    bmiTell :: (RealFloat a) => a -> String
    bmiTell bmi
    | bmi <= 18.5 = "You're underweight, you emo, you!"
    | bmi <= 25.0 = "You're supposedly normal. Pffft, I bet you're ugly!"
    | bmi <= 30.0 = "You're fat! Lose some weight, fatty!"
    | otherwise = "You're a whale, congratulations!"
    ```

    * Guards can be combined with patterns: If all guards of a function evaluate to False, evaluation falls through to the next pattern

    * Guards can have as many parameters as we want

    ```
    bmiTell :: (RealFloat a) => a -> a -> String
    bmiTell weight height
    | weight / height ^ 2 <= 18.5 = "You're underweight, you emo, you!"
    | weight / height ^ 2 <= 25.0 = "You're supposedly normal. Pffft, I bet you're ugly!"
    | weight / height ^ 2 <= 30.0 = "You're fat! Lose some weight, fatty!"
    | otherwise = "You're a whale, congratulations!"
    ```

    ```
    max' :: (Ord a) => a -> a -> a
    max' a b
    | a > b = a
    | otherwise = b
    ```

    ```
    myCompare :: (Ord a) => a -> a -> Ordering
    a `myCompare` b
    | a > b = GT
    | a == b = EQ
    | otherwise = LT
    ```

    * Guards can use a `where` block to define functions that are only visible inside the guard function

    ```
    bmiTell :: (RealFloat a) => a -> a -> String
    bmiTell weight height
    | bmi <= skinny = "You're underweight, you emo, you!"
    @@ -304,137 +379,186 @@ This is a summary of the "Learn You A Haskell" online book under http://learnyou
    skinny = 18.5
    normal = 25.0
    fat = 30.0
    ```

    * Combined with a patteren match

    ```
    ...
    where bmi = weight / height ^ 2
    (skinny, normal, fat) = (18.5, 25.0, 30.0)
    ```

    * More Examples

    ```
    initials :: String -> String -> String
    initials firstname lastname = [f] ++ ". " ++ [l] ++ "."
    where (f:_) = firstname
    (l:_) = lastname
    ```

    ```
    calcBmis :: (RealFloat a) => [(a, a)] -> [a]
    calcBmis xs = [bmi w h | (w, h) <- xs]
    where bmi weight height = weight / height ^ 2
    ```

    * *Let bindings* are similar to where bindings. Their form is `let <bindings> in <expression>`.

    ```
    cylinder :: (RealFloat a) => a -> a -> a
    cylinder r h =
    let sideArea = 2 * pi * r * h
    topArea = pi * r ^2
    in sideArea + 2 * topArea
    ```

    * The difference between let bindings and where bindings is that let bindings are expressions, just like if statements:

    ```
    4 * (if 10 > 5 then 10 else 0) + 2 (42)
    ```

    ```
    4 * (let a = 9 in a + 1) + 2 (42)
    ```

    * Let bindings can be used to introduce functions in a local scope

    ```
    [let square x = x * x in (square 5, square 3, square 2)] ( [(25,9,4)] )
    ```

    * To let bind several variables they get separated by a semicolon

    ```
    (let a = 100; b = 200; c = 300 in a*b*c, let foo="Hey "; bar = "there!" in foo ++ bar)
    ```

    * Let bindings can be used with pattern matching

    ```
    (let (a,b,c) = (1,2,3) in a+b+c) * 100 (600)
    ```

    * Let bindings can be used in list comprehensions

    ```
    calcBmis :: (RealFloat a) => [(a, a)] -> [a]
    calcBmis xs = [bmi | (w, h) <- xs, let bmi = w / h ^ 2]
    ```

    * Predicates come after the let binding

    ```
    calcBmis :: (RealFloat a) => [(a, a)] -> [a]
    calcBmis xs = [bmi | (w, h) <- xs, let bmi = w / h ^ 2, bmi >= 25.0]
    ```

    * *Case expressions* are very similar to pattern matching:

    ```
    head' :: [a] -> a
    head' [] = error "No head for empty lists!"
    head' (x:_) = x
    ```

    ```
    head' :: [a] -> a
    head' xs = case xs of [] -> error "No head for empty lists!"
    (x:_) -> x
    ```

    ```
    case expression of pattern -> result
    pattern -> result
    pattern -> result
    ...
    ```

    * Pattern matching can only be used with function definitions. Cases expressions work everywhere

    ```
    describeList :: [a] -> String
    describeList xs = "The list is " ++ case xs of [] -> "empty."
    [x] -> "a singleton list."
    xs -> "a longer list."
    ```


    # 4. Recursion

    * Try to start with the edge cases

    ```
    maximum' :: (Ord a) => [a] -> a
    maximum' [] = error "maximum of empty list"
    maximum' [x] = x
    maximum' (x:xs)
    | x > maxTail = x
    | otherwise = maxTail
    where maxTail = maximum' xs
    ```

    ```
    maximum' :: (Ord a) => [a] -> a
    maximum' [] = error "maximum of empty list"
    maximum' [x] = x
    maximum' (x:xs) = max x (maximum' xs)
    ```

    ```
    replicate' :: (Num i, Ord i) => i -> a -> [a]
    replicate' n x
    | n <= 0 = []
    | otherwhise = x:replicate' (n-1) x
    ```

    ```
    take' :: (Num i, Ord i) => i -> [a] -> [a]
    take' n _
    | n <= 0 = []
    take' _ [] = []
    take' n (x:xs) = x : take' (n-1) xs
    ```

    ```
    reverse' :: [a] -> [a]
    reverse' [] = []
    reverse' (x:xs) = reverse' xs ++ [x]
    ```

    ```
    repeat' :: a -> [a]
    repeat' x = x:repeat' x
    ```

    ```
    zip' :: [a] -> [b] -> [(a,b)]
    zip' _ [] = []
    zip' [] _ = []
    zip' (x:xs) (y:ys) = (x,y):zip' xs ys
    ```

    ```
    elem' :: (Eq a) => a -> [a] -> Bool
    elem' a [] = False
    elem' a (x:xs)
    | a == x = True
    | otherwise = a `elem'` xs
    ```

    * Quicksort can be implemented very elegantly. The main algorithm is "a sorted list is a list that has all the values smaller than (or equal to) the head of the list in front (and those values are sorted), then comes the head of the list in the middle and then come all the values that are bigger than the head (they're also sorted)"

    ```
    quicksort :: (Ord a) => [a] -> [a]
    quicksort [] = []
    quicksort (x:xs) =
    let smallerSorted = quicksort [a | a <- xs, a <= x]
    biggerSorted = quicksort [a | a <- xs, a > x]
    in smallerSorted ++ [x] ++ biggerSorted
    ```


    # 5. Higher order functions
  29. @mikehaertl mikehaertl created this gist Aug 4, 2012.
    440 changes: 440 additions & 0 deletions gistfile1.md
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,440 @@
    Haskell Overview
    ----------------

    This is a summary of the "Learn You A Haskell" online book under http://learnyouahaskell.com/chapters.

    # 1. Introduction

    * Haskell is a functional programming language.
    * "what it is" over "what to do"
    * Haskell is *lazy* - no calculation until a result is used
    * Statically typed - errors are caught on compile time
    * Type inference - it auto-detects the right type e.g. for a = 5 + 4
    * GHC is the most widely used Haskell compiler
    * To load a file you do:

    l: myfunctions.hs


    # 2. Starting Out

    * Interactive GHC is started with `ghci`
    * Simple arithmetic:

    2 + 15
    49 * 100
    1892 - 1472
    5 / 2
    50 * 100 - 4999
    50 * (100 - 4999)

    * Surround negative numbers with brackets:

    5 * (-3)

    * Boolean algebra with `True`, `False`, `not`, `&&`and `||`

    not (True && True)

    * Test for equality with `==` and inequality with `/=`
    * *infix* functions like `*` stand between the operators
    * Most functions are *prefix* functions:

    - succ 8 : successor (9)
    - min 3 4 : minimum of 2 values (3)
    - max 4 5 : maximum of 2 values (5)
    - div 13 6 : integral division of 2 integers (2)
    - odd 5 : wether number is odd (True)

    * Prefix functions can be written as infix with backticks:

    div 92 10
    92 `div` 10

    * Functions are defined with `=`

    doubleMe x = x + x
    doubleUs x y = x*2 + y*2

    * `if` have a `then` and always require a `else`

    doubleSmallNumber x = if x > 100
    then x
    else x*2

    * `if` is also an expression

    * Lists are *homogenous* (all elements have the same type):

    lostNumbers = [4,8,15,16,23,42]
    someString = "Some string"

    * Use `++` to put two lists together (goes through the complete list!)

    [1,2,3,4] ++ [6,7,8]
    "Hello" ++ " " ++ "world"

    * Use `:` to prepend LHS to RHS

    'A':" SMALL CAT"
    1:[2,3,4,5]
    1:2:3:[]

    * Use `!!` to get an element by index (0 based, index must exist)

    "Steve Buscemi" !! 6

    * Use `<`, `<=`, `>` and `>=` to lexographically compare lists

    * List ranges are defined with `..`:

    [1..20]
    ['a'..'z']

    * Ranges can define a step size

    [2,4..20] ([2,4,6,8,10,12,16,18,20])
    [3,6..20] ([3,6,9,12,15,18])
    [20,19..15] ([20,19,18,17,16,15])

    * List methods

    - head [5,4,3] : first element of a list (5)
    - tail [5,4,3] : tail without head ([4,3])
    - last [5,4,3] : last element of a list (3)
    - init [5,4,3] : list without tail ([5,4])
    - length [5,4,3] : number of elements (3)
    - null [5,4,3] : wether list is empty (False)
    - reverse [5,4,3] : reverse list ([3,4,5])
    - take 3 [5,4,3,2,1] : extract number of elements from list start ([5,4,3])
    - drop 3 [5,4,3,2,1] : drop first elements of a list ([2,1])
    - maximum [5,4,3,2,1] : maximum of orderable list (5)
    - minimum [5,4,3,2,1] : minimum of orderable list (1)
    - sum [5,4,3] : sum of number list (12)
    - product [5,4,3] : product of number list (60)
    - 4 `elem` [5,4,3] : wether element is in list, usually infixed (True)
    - take 10 (cycle [1,2,3]) : repeat the list elements ([1,2,3,1,2,3,1,2,3,1])
    - take 10 (repeat 5) : repeat the element ([5,5,5,5,5,5,5,5,5,5])
    - replicate 3 10 : repeat the element a number of times ([10,10,10])

    * List comprehensions are similar to mathematical equations

    [x*2 | x <- [1..5]] ([2,4,6,8,10])

    * *Predicates* are conditions for list comprehensions

    [x*2 | x <- [1..5], x*2 >= 5] ([6,8,10])

    * There can be more predicates

    [ x | x <- [10..20], x /= 10, x /= 15, x /= 19]

    * Comprehensions can be put inside a function

    boomBangs xs = [if x < 10 then "BOOM!" else "BANG!" | x <- xs, odd x]

    * Comprehensions can draw from several lists, which multiplies the lengths

    [ x*y | x <- [2,3], y <- [3,4,5]] ([6,8,10,9,12,15])

    * `_` is a dummy placeholder for a unused value

    length' xs = sum [1 | _ <- xs]

    * List comprehensions can be nested

    let xxs = [[1,2,3],[2,3,4],[4,5]]
    [ [x | x <- xs, even x] | xs <- xxs] ([[2],[2,4],[4]]

    * Tuples can contain several types, but for the type of two Tuples to be the same, the number and types of their elements must match

    (1,2)
    [(1,2), (3,2), (4,9)]
    [("Johnny", "Walker", 38), ("Kate", "Middleton", 27)]

    * Tuple functions

    - fst (8,11) : returns first component of a pair (8)
    - snd (9,"Hey") : returns second component of a pair ("Hey")
    - zip [1..3] ['a'..'c'] : combine two lists to a list of tuples ( [(1,'a'), (2,'b'), (3,'c')] )


    # 3. Types and Typeclasses

    * Types always start with an uppercase letter

    * Use `:t` to get a type of something

    :t 'a' ('a' :: Char)
    :t "HELLO" ("HELLO" :: [Char])
    :t (True, 'a') ( (True,'a') :: (Bool, Char) )

    * All functions should use a type declaration with `::` ("has type of"). Multiple arguments are also separeted with `->` just like the type declaration itself.

    removeUppercase :: [Char] -> [Char]
    removeUppercase :: String -> String (same as above)
    addThree :: Int -> Int -> Int -> Int
    addThree x y z = x + y + z

    * Common types

    - Int : Integer
    - Integer : Integer (big)
    - Float : Floating point
    - Double : Floating point with double precision
    - Bool : Boolean
    - Char : Character
    - Tuples, as mentioned in chapter 2
    - Ordering : Can be `GT`, `LT` or `EQ`

    * Type variables can be used in function declarations. They mean "any type"

    :t head (head :: [a] -> a)
    :t fst (fst :: (a, b) -> a)

    * Typeclasses are like interfaces for types. If a type is part of a typeclass it implements that class' behavior. The `=>` symbol separates the *class constraint* from the declaration:

    :t (==) ( (==) :: (Eq a) => a -> a -> Bool )

    - Eq : supports equality testing
    - Ord : can have ordering
    - Show : can be presented as string
    - Read : can be read from a string
    - Enum : ordered type which can be enumerated
    - Bounded : have an upper and lower bound
    - Num : can act like a number
    - Integral : can act like an integral number
    - Floating : can act like a floating point number

    * Related functions

    - 5 `compare` 3 : takes two `Ord` members of same type and returns a `Ordering` (GT)
    - show 3 : takes a `Show` and returns a `String` ("3")
    - read "True" : takes a `Read` and returns a `Read` (True)
    - succ LT : takes a `Enum` and returns next element (GT)
    - pred 'b' : takes a `Enum` and returns previous element ('a')
    - minBound :: Bool : takes a `Bounded` and returns lower bound (False)
    - maxBound :: Bool : takes a `Bounded` and returns lower bound (True)
    - fromIntegral 5 : takes a `Integral` and returns a `Num`

    * Type annotations define the type of ambiguous expressions

    (read "5" :: Float) * 4


    # 3. Syntax in Functions

    * Functions can be defined with *Pattern Matching*. Patterns make sure that the input matches a specified pattern. The first matching pattern is executed. There should always be a catch-all pattern at the end

    lucky :: (Integral a) => a -> String
    lucky 7 = "LUCKY NUMBER SEVEN!"
    lucky x = "Sorry, you're out of luck, pal!"

    factorial :: (Integral a) => a -> a
    factorial 0 = 1
    factorial n = n * factorial (n - 1)

    addVectors :: (Num a) => (a, a) -> (a, a) -> (a, a)
    addVectors (x1, y1) (x2, y2) = (x1 + x2, y1 + y2)

    head' :: [a] -> a
    head' [] = error "Can't call head on an empty list, dummy!"
    head' (x:_) = x

    tell :: (Show a) => [a] -> String
    tell [] = "The list is empty"
    tell (x:[]) = "The list has one element: " ++ show x
    tell (x:y:[]) = "The list has two elements: " ++ show x ++ " and " ++ show y
    tell (x:y:_) = "This list is long. The first two elements are: " ++ show x ++ " and " ++ show y

    length' :: (Num b) => [a] -> b
    length' [] = 0
    length' (_:xs) = 1 + length' xs

    sum' :: (Num a) => [a] -> a
    sum' [] = 0
    sum' (x:xs) = x + sum' xs

    * The *as pattern* is used to reference the "whole thing": Put a name followed by `@` in front of the pattern:

    capital :: String -> String
    capital "" = "Empty string, whoops!"
    capital all@(x:xs) = "The first letter of " ++ all ++ " is " ++ [x]

    * *Guards* are similar to if statements and check for boolean conditions. There's no `=` after the function name:

    bmiTell :: (RealFloat a) => a -> String
    bmiTell bmi
    | bmi <= 18.5 = "You're underweight, you emo, you!"
    | bmi <= 25.0 = "You're supposedly normal. Pffft, I bet you're ugly!"
    | bmi <= 30.0 = "You're fat! Lose some weight, fatty!"
    | otherwise = "You're a whale, congratulations!"

    * Guards can be combined with patterns: If all guards of a function evaluate to False, evaluation falls through to the next pattern

    * Guards can have as many parameters as we want

    bmiTell :: (RealFloat a) => a -> a -> String
    bmiTell weight height
    | weight / height ^ 2 <= 18.5 = "You're underweight, you emo, you!"
    | weight / height ^ 2 <= 25.0 = "You're supposedly normal. Pffft, I bet you're ugly!"
    | weight / height ^ 2 <= 30.0 = "You're fat! Lose some weight, fatty!"
    | otherwise = "You're a whale, congratulations!"

    max' :: (Ord a) => a -> a -> a
    max' a b
    | a > b = a
    | otherwise = b

    myCompare :: (Ord a) => a -> a -> Ordering
    a `myCompare` b
    | a > b = GT
    | a == b = EQ
    | otherwise = LT

    * Guards can use a `where` block to define functions that are only visible inside the guard function

    bmiTell :: (RealFloat a) => a -> a -> String
    bmiTell weight height
    | bmi <= skinny = "You're underweight, you emo, you!"
    | bmi <= normal = "You're supposedly normal. Pffft, I bet you're ugly!"
    | bmi <= fat = "You're fat! Lose some weight, fatty!"
    | otherwise = "You're a whale, congratulations!"
    where bmi = weight / height ^ 2
    skinny = 18.5
    normal = 25.0
    fat = 30.0

    * Combined with a patteren match

    ...
    where bmi = weight / height ^ 2
    (skinny, normal, fat) = (18.5, 25.0, 30.0)

    * More Examples

    initials :: String -> String -> String
    initials firstname lastname = [f] ++ ". " ++ [l] ++ "."
    where (f:_) = firstname
    (l:_) = lastname

    calcBmis :: (RealFloat a) => [(a, a)] -> [a]
    calcBmis xs = [bmi w h | (w, h) <- xs]
    where bmi weight height = weight / height ^ 2

    * *Let bindings* are similar to where bindings. Their form is `let <bindings> in <expression>`.

    cylinder :: (RealFloat a) => a -> a -> a
    cylinder r h =
    let sideArea = 2 * pi * r * h
    topArea = pi * r ^2
    in sideArea + 2 * topArea

    * The difference between let bindings and where bindings is that let bindings are expressions, just like if statements:

    4 * (if 10 > 5 then 10 else 0) + 2 (42)

    4 * (let a = 9 in a + 1) + 2 (42)

    * Let bindings can be used to introduce functions in a local scope

    [let square x = x * x in (square 5, square 3, square 2)] ( [(25,9,4)] )

    * To let bind several variables they get separated by a semicolon

    (let a = 100; b = 200; c = 300 in a*b*c, let foo="Hey "; bar = "there!" in foo ++ bar)

    * Let bindings can be used with pattern matching

    (let (a,b,c) = (1,2,3) in a+b+c) * 100 (600)

    * Let bindings can be used in list comprehensions

    calcBmis :: (RealFloat a) => [(a, a)] -> [a]
    calcBmis xs = [bmi | (w, h) <- xs, let bmi = w / h ^ 2]

    * Predicates come after the let binding

    calcBmis :: (RealFloat a) => [(a, a)] -> [a]
    calcBmis xs = [bmi | (w, h) <- xs, let bmi = w / h ^ 2, bmi >= 25.0]

    * *Case expressions* are very similar to pattern matching:

    head' :: [a] -> a
    head' [] = error "No head for empty lists!"
    head' (x:_) = x

    head' :: [a] -> a
    head' xs = case xs of [] -> error "No head for empty lists!"
    (x:_) -> x

    case expression of pattern -> result
    pattern -> result
    pattern -> result
    ...

    * Pattern matching can only be used with function definitions. Cases expressions work everywhere

    describeList :: [a] -> String
    describeList xs = "The list is " ++ case xs of [] -> "empty."
    [x] -> "a singleton list."
    xs -> "a longer list."


    # 4. Recursion

    * Try to start with the edge cases

    maximum' :: (Ord a) => [a] -> a
    maximum' [] = error "maximum of empty list"
    maximum' [x] = x
    maximum' (x:xs)
    | x > maxTail = x
    | otherwise = maxTail
    where maxTail = maximum' xs

    maximum' :: (Ord a) => [a] -> a
    maximum' [] = error "maximum of empty list"
    maximum' [x] = x
    maximum' (x:xs) = max x (maximum' xs)

    replicate' :: (Num i, Ord i) => i -> a -> [a]
    replicate' n x
    | n <= 0 = []
    | otherwhise = x:replicate' (n-1) x

    take' :: (Num i, Ord i) => i -> [a] -> [a]
    take' n _
    | n <= 0 = []
    take' _ [] = []
    take' n (x:xs) = x : take' (n-1) xs

    reverse' :: [a] -> [a]
    reverse' [] = []
    reverse' (x:xs) = reverse' xs ++ [x]

    repeat' :: a -> [a]
    repeat' x = x:repeat' x

    zip' :: [a] -> [b] -> [(a,b)]
    zip' _ [] = []
    zip' [] _ = []
    zip' (x:xs) (y:ys) = (x,y):zip' xs ys

    elem' :: (Eq a) => a -> [a] -> Bool
    elem' a [] = False
    elem' a (x:xs)
    | a == x = True
    | otherwise = a `elem'` xs

    * Quicksort can be implemented very elegantly. The main algorithm is "a sorted list is a list that has all the values smaller than (or equal to) the head of the list in front (and those values are sorted), then comes the head of the list in the middle and then come all the values that are bigger than the head (they're also sorted)"

    quicksort :: (Ord a) => [a] -> [a]
    quicksort [] = []
    quicksort (x:xs) =
    let smallerSorted = quicksort [a | a <- xs, a <= x]
    biggerSorted = quicksort [a | a <- xs, a > x]
    in smallerSorted ++ [x] ++ biggerSorted


    # 5. Higher order functions