19 Oct

# Lists

Empty list: `[]`

Prepending:

``````> 1 : [2, 3]
[1, 2, 3]

> 'a' : "bcd"
"abcd"
``````

Appending/concatenating:

``````> [1, 2] ++ [3, 4]
[1, 2, 3, 4]

>  ++ [2, 3]
[1, 2, 3]

> "ab" ++ "cd"
"abcd"
``````

Extracting:

``````> head [1, 2, 3]
1

> tail [1, 2, 3]
[2, 3]

> last [1, 2, 3]
3

> drop 2 [1, 2, 3, 4, 5]  -- last two elements
[4, 5]

> "abc" !! 1  -- arbitrary index
'b' -- zero-based index
``````

Signature types:

``````squares :: [Int] -> [Int]  -- takes a list of integers and returns a list of integers
``````

Ranges:

``````> [1..5]
[1,2,3,4,5]

> [5..1]  -- won't implicitly work for reverse
[]

> [1..]
[1, 2, 3, 4, 5, 6, 7, ...]  -- will run to infinity

> ['a'..'e']  -- letters too
"abcde"
``````

# Recursion

Square every element: `squares [1, 2, 3]` is `[1, 4, 9]`

Manipulating elements in a list one by one, the following are equivalent:

``````-- descriptive, list comprehension
squares xs = [x^2 | x <- xs]  -- x^2 is equivalent to x*x

-- equational recursion
squares []     = []
squares (x:xs) = x^2 : squares xs  -- list with head x and tail xs

-- conditional recursion
squares l =
if l == [] then []
else x^2 : squares xs
xs = tail l

-- conditional recursion (with let..in)
squares l =
if l == [] then []
else let x  = head l
xs = tail l
in x^2 : squares xs
``````

Square only even elements: `squareEvens [1, 2, 3, 4]` is `[4, 16]`

Manipulating elements if they match a condition, the following are equivalent:

``````-- descriptive
squareEvens xs = [x^2 | x <- xs, even x]  -- 'even' is a built-in equivalent to (x `mod` 2 == 0)

-- pattern matching
squareEvens [] = []
squareEvens (x:xs)
| even x    = x : squareEvens xs
| otherwise = squareEvens xs
``````