% Intro to Haskell, day 2 % G Bordyugov % Oct 2016
- Get some coffee - you'll need your grey matter :-)
- Exercises with lists and maps
- Algebraic data types
import Prelude hiding ((.))
Using
map :: (a -> b) -> [a] -> [b]
reverse :: String -> String
words :: String -> [String]
unwords :: [String] -> String
write a function that will reverse letters in all words in a string.
I.e.
reverseWords "bla bli blu" -- => "alb ilb ulb"
Check the type of the reverseWords
.
Using
map :: (a -> b) -> [a] -> [b]
reverse :: String -> String
words :: String -> [String]
unwords :: [String] -> String
write a function that will reverse letters in all words in a string. Solution:
reverseWords :: String -> String
reverseWords = unwords . (map reverse) . words
Write the type signature and definition of the function composition (.), as in
countWords :: String -> Int
countWords = length . words
(words
splits a string into single words by spaces)
(.) :: (b -> c) -> (a -> b) -> (a -> c)
Prefix and infix notations can be used interchangeably:
either
f . g = \x -> f (g x)
or
(.) f g = \x -> f (g x)
map :: (a -> b) -> [a] -> [b]
map (+1) [1, 2, 3] -- => [2, 3, 4]
map (+1) [[1, 2], [3, 4], [5,6]]
-- => type error, won't even compile
Solution:
(map . map) (+1) [[1, 2], [3, 4], [5,6]]
Clear separation of what to do (+1)
and the data structure access
(map . map)
.
Very common pattern in Haskell!
We have for (map . map)
(.) :: (b -> c) -> (a -> b) -> (a -> c)
map :: (u -> v) -> ([u] -> [v])
map :: (p -> q) -> ([p] -> [q])
We have for (map . map)
(.) :: (b -> c) -> (a -> b) -> (a -> c)
map :: (u -> v) -> ([u] -> [v])
-------- ------------
a -> b
map :: (p -> q) -> ([p] -> [q])
-------- ------------
b -> c
from those types, it follows:
a = u -> v
b = [u] -> [v]
b = p -> q
c = [p] -> [q]
From here, it follows that p = [u], q = [v]
and following
c = [p] -> [q] = [[u]] -> [[v]]
and finally the type of (map . map)
a -> c = (u -> v) -> ([[u]] -> [[v]])
Ta-da!
Understand and derive the type of
map map :: [a -> b] -> [[a] -> [b]]