doubleMe x = x + x doubleUs x y = (doubleMe x) + (doubleMe y) doubleSmallNumber x = if x > 100 then x else (x * 2) doubleSmallNumber' x = (doubleSmallNumber x) + 1 listConcatNums = [1,2,3,4] ++ [9,10,11,12] -- Strings are lists of chars listConcatChars = "hello" ++ " " ++ "world" -- Cons prepends a value to a list: listPrependNum xs = 5:xs listPrependA xs = 'A':xs -- Access item at list index: listFirstValue xs = xs !! 0 -- head, tail, last, init are useful built-ins for list operations -- head - get first element -- tail - get everything except first element -- last - get last element -- init - get everything except last element -- length - get length of list -- null - check if list is empty -- reverse - reverses a list -- take - get the first n elements of a list, if possible -- drop - drop the first n elements of a list, if possible -- maximum - get largest element in list -- minimum - get smallest element in list -- sum - add up all numbers in list -- product - product of all numbers in list -- elem - check if an item appears in a list: 4 `elem` [3,4,5,6] == True -- Texas ranges: getRangeThru n = [1..n] -- getRangeThru 4 == [1,2,3,4] getEvensThru n = [2,4..n] -- getEvensThru 8 == [2,4,6,8] -- Can use infinite ranges. e.g., get first 10 multiples of 13: first10of13 = take 10 [13,26,..] -- cycle - cycles a list infinitely - e.g. cycle [1,2,3] == [1,2,3,1,2,3,..] -- repeat - takes an element and produces an infinite list - e.g. repeat 5 == [5,5..] -- replicate - get a list of some item n times - e.g. replicate 3 10 == [10,10,10] -- List comprehension, like set comprehension in math: first10Evens = [x*2 | x <- [1..10]] -- == [2,4,6,8,10,12,14,16,18,20] -- We can constrain x further using predicates: first10EvensWhoseDoublesAreGreaterThan12 = [x*2 | x <- [1..10], x*2 >= 12] -- == [12,14,16,18,20] -- Say, e.g., we want to filter a list for odd numbers only, replacing those less than 10 with BOOM, else BANG boomBangs xs = [ if x < 10 then "BOOM!" else "BANG!" | x <- xs, odd x ] -- Can have multiple predicates, and multiple domains: multiRange = [ x*y | x <- [1..3], y <- [2..4] ] -- result will have length 9 -- Since strings are lists, we can use list comprehension to work on them, e.g. removeNonUppercase st = [ c | c <- st, c `elem` ['A'..'Z']] -- Tuples -- fst - get the first item in a 2-tuple -- snd - get the second item in a 2-tuple -- zip - create pairs from 2 lists: zipTest1 = zip [1..3] ["one", "two", "three"] -- == [(1,"one"),(2,"two"),(3,"three")] -- zip clips to the shortest list: zipTest2 = zip [1..] ["one", "two"] -- == [(1,"one"),(2,"two")]