Types¶

Type annotations¶

• Every expression can be annotated with a type signature
• Types can be generic and have type variables

Count with type signature¶

In [ ]:
count' :: [a] -> Int -> Int
count' [] result = result
count' (first:rest) result = count' rest (result + 1)

In [ ]:
count :: [a] -> Int
count list = count' list 0


Laziness¶

Nonstrict evaluation¶

• Expressions are not evaluated until their value is needed
• Haskell implements this using lazy evaluation

Laziness¶

Infinite lists¶

In [ ]:
allNumbersStartingAt n = n : allNumbersStartingAt (n+1)


{.haskell .fragment} → [0,1,2,3,4]

Repeat a list endlessly¶

In [ ]:
take 11 (cycle ['S','O','S', '-'])


{.haskell .fragment} → "SOS-SOS-SOS"

Partial function application¶

Infix functions (operators)¶

• Can also be partially applied
• Just wrap them in parenthesis and omit one operand

Example /¶

In [ ]:
divideByTen :: Fractional a => a -> a
divideByTen = (/ 10)


Example elem¶

In [ ]:
isUpperCase :: Char -> Bool
isUpperCase = (elem ['A' .. 'Z'])


Functions as arguments¶

Example: Do something twice¶

In [ ]:
applyTwice :: (a -> a) -> a -> a
applyTwice f x = f (f x)

• First parameter is a function of type (a -> a)
• Second parameter is a value of type a

Things to do twice¶

In [ ]:
applyTwice (+3) 10
applyTwice ("Hello, " ++) "who is there?"
applyTwice (3:) [1]


zipWith' implementation¶

Recursive function with pattern matching¶

In [ ]:
zipWith' :: (a -> b -> c) -> [a] -> [b] -> [c]
zipWith' f [] bs = []
zipWith' f as [] = []
zipWith' f (a:as) (b:bs) = f a b : zipWith' f as bs


zipWith' applications¶

Guess what the results are¶

In [ ]:
zipWith' (+) [1, 2, 3] [1, 2, 3]
zipWith' (*) (replicate 4 3) [1..]
zipWith' max [3,7,2] [4,1,6]
zipWith' (++) ["James T. ", "", "Nyota "] ["Kirk", "Spock", "Uhura"]

In [ ]:
fibs = 0 : 1 : zipWith' (+) fibs (tail fibs)


Assignment 1¶

Fibonacci number¶

In [ ]:
fibs :: [Integer]
fibs = 0 : 1 : zipWith (+) fibs (tail fibs)


Mapping¶

Function map¶

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

• Take a function
• Apply to every element of the list
• Collect the results in a list

Mapping¶

Examples¶

In [ ]:
map ("Beam me up, " ++) ["Kirk", "Spock", "Scotty"]
map (replicate 3) [1, 2, 3]
map fst [('A', 'B'), ('C', 'D'), ('E', 'F')]
map snd [('A', 'B'), ('C', 'D'), ('E', 'F')]


Filtering¶

Function filter¶

In [ ]:
filter' :: (a -> Bool) -> [a] -> [a]
filter' _ [] = []
filter' p (x:xs)
| p x = x : filter' p xs
| otherwise = filter' p xs

• Take a predicate
• Apply to each element of the list
• Assemble new list of elements that satisfy the predicate

Filtering¶

Examples¶

In [ ]:
filter (>3) [1,5,3,2,1,6,4,3,2,1]
filter even [1,5,3,2,1,6,4,3,2,1]
filter (elem ['a'..'z']) "Beam me up, Scotty!"
filter (elem ['A'..'Z']) "Beam me up, Scotty!"