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]
> [1] ++ [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
where x = head l
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