Jürgen Cito
December 10, 2013
310

Haskell Private is a format where students of the Functional Programming course[1] at Vienna UT[2] can get feedback on their submitted assignments concerning their functional style.

We summarized our findings and presented them in front of a separate class called 'Haskell Live' on November 29th.

Jürgen Cito

December 10, 2013

Transcript

1. Lessons learned at Haskell Private Vienna University of Technology J¨

urgen Cito, Michael Schr¨ oder Haskell Live Vienna University of Technology November 29th, 2013 1 / 12
2. A note on the code examples • The examples on

these slides are for ghci • Hugs does not support let-expressions on the command prompt 2 / 12
3. Operations on Lists • Common task in FP is to

work on lists • Ways we’ve seen more often: Recursion, List comprehension • Convenient ways to work with lists: • map • ﬁlter • zipWith 3 / 12
4. Working with lists – map Common task: Transforming elements in

the list Source Element → Target Element map :: (a -> b) -> [a] -> [b] 4 / 12
5. Working with lists – map map :: (a -> b)

-> [a] -> [b] Example: let words = ["my", "new", "string", "list"] let wordsWithLength word = (word, length word) map wordsWithLength words > [("my",2),("new",3),("string",6),("list",4)] 4 / 12
6. Anonymous Functions • Sometimes it’s more convenient to pass on

a function without giving it a name. • Nameless functions, also called Lambda Expressions • from Lambda calculus: λx.x + 1 • in Haskell: \x -> x + 1 5 / 12
7. Anonymous Functions Example: let words = ["my", "new", "string", "list"]

map (\word -> (word, length word)) words > [("my",2),("new",3),("string",6),("list",4)] 5 / 12
8. Anonymous Functions Example: let words = ["my", "new", "string", "list"]

map (\word -> (word, length word)) words > [("my",2),("new",3),("string",6),("list",4)] -- ’it’ provides the last evaluated result in ghci map (\(a, b) -> (b, replicate b ’|’, a)) it > [(2,"||","my"),(3,"|||","new"),(6,"||||||","string"),(4,"||||","list")] 5 / 12
9. Working with lists – ﬁlter Retain elements that return true

on given function, drop all others filter :: (a -> Bool) -> [a] -> [a] 6 / 12
10. Working with lists – ﬁlter filter :: (a -> Bool)

-> [a] -> [a] Example: let wl = [("my",2),("new",3),("string",6),("list",4)] filter (\x -> snd x >= 4) wl > [("string",6),("list",4)] 6 / 12
11. Working with lists – ﬁlter filter :: (a -> Bool)

-> [a] -> [a] Example: let wl = [("my",2),("new",3),("string",6),("list",4)] filter (\x -> snd x >= 4) wl > [("string",6),("list",4)] let count = [1,2,0] let candidateCount = [("Carla",1),("JD",2),("Turk",0)] filter (\x -> snd x == minimum count) candidateCount > [("Turk",0)] 6 / 12
12. Working with lists – zipWith Merge two lists into one

with the help of a function zipWith :: (a -> b -> c) -> [a] -> [b] -> [c] 7 / 12
13. Working with lists – zipWith zipWith :: (a -> b

-> c) -> [a] -> [b] -> [c] Example: let candidates = ["Carla", "JD", "Turk"] let count = [1,2,0] zipWith (\x y -> show y ++ ": " ++ x) candidates count > ["1: Carla", "2: JD", "0: Turk"] 7 / 12
14. \$ Operator • \$ Function application – right-associative, lowest precedence

• ’Normal’ function application – left-associative, very high precedence • \$ is a convenience function to avoid parentheses 8 / 12
15. \$ Operator infixr 0 \$ (\$) :: (a -> b)

-> a -> b f \$ x = f x 8 / 12
16. \$ Operator infixr 0 \$ (\$) :: (a -> b)

-> a -> b f \$ x = f x Example: sum (filter (> 10) (map (*2) [2..10])) > 80 8 / 12
17. \$ Operator infixr 0 \$ (\$) :: (a -> b)

-> a -> b f \$ x = f x Example: sum (filter (> 10) (map (*2) [2..10])) > 80 sum \$ filter (> 10) \$ map (*2) [2..10] > 80 8 / 12
18. Function Composition with . Function composition is the act of

pipelining the result of one function, to the input of another, creating an entirely new function.1 (.) :: (b -> c) -> (a -> b) -> a -> c f . g = \x -> f (g x) 9 / 12
19. Function Composition with . (.) :: (b -> c) ->

(a -> b) -> a -> c f . g = \x -> f (g x) (reverse . sort) [2,8,7,10,1,9,5,3,4,6] > [10,9,8,7,6,5,4,3,2,1] 9 / 12
20. Function Composition with . (.) :: (b -> c) ->

(a -> b) -> a -> c f . g = \x -> f (g x) (reverse . sort) [2,8,7,10,1,9,5,3,4,6] > [10,9,8,7,6,5,4,3,2,1] reverse . sort \$ [2,8,7,10,1,9,5,3,4,6] > [10,9,8,7,6,5,4,3,2,1] 9 / 12
21. Function Composition with . (.) :: (b -> c) ->

(a -> b) -> a -> c f . g = \x -> f (g x) (reverse . sort) [2,8,7,10,1,9,5,3,4,6] > [10,9,8,7,6,5,4,3,2,1] reverse . sort \$ [2,8,7,10,1,9,5,3,4,6] > [10,9,8,7,6,5,4,3,2,1] rsort :: Ord a => [a] -> [a] rsort = reverse . sort rsort [2,8,7,10,1,9,5,3,4,6] > [10,9,8,7,6,5,4,3,2,1] 9 / 12
22. Function Composition with . (.) :: (b -> c) ->

(a -> b) -> a -> c f . g = \x -> f (g x) (reverse . sort) [2,8,7,10,1,9,5,3,4,6] > [10,9,8,7,6,5,4,3,2,1] reverse . sort \$ [2,8,7,10,1,9,5,3,4,6] > [10,9,8,7,6,5,4,3,2,1] rsort :: Ord a => [a] -> [a] rsort = reverse . sort rsort [2,8,7,10,1,9,5,3,4,6] > [10,9,8,7,6,5,4,3,2,1] remove p = filter (not . p) remove (\x -> mod x 2 == 0) [1..10] > [1,3,5,7,9] 9 / 12
23. @ – as-pattern Assigns matched pattern after ”@” to the

symbol before ”@” so that this symbol can be used in the right-hand side expression1 1http: //zvon.org/other/haskell/Outputsyntax/As-patterns_reference.html 10 / 12
24. @ – as-pattern Example: rearrangeLostCandidates [] = [] rearrangeLostCandidates vote@(x:xs)

| elem x lostCandidates = xs++[x] | otherwise = vote 10 / 12
25. @ – as-pattern Example: rearrangeLostCandidates [] = [] rearrangeLostCandidates vote@(x:xs)

| elem x lostCandidates = xs++[x] | otherwise = vote delete :: SozNr -> Tree -> Tree delete _ Nil = Nil delete s@(Sznr snr) (Node n@(_, _, Sznr nr) left right) | snr < nr = Node n (delete s left) right | snr > nr = Node n left (delete s right) 10 / 12
26. Higher Order Functions A higher-order function is a function that

takes other functions as arguments or returns a function as result.1 ⇒ map, ﬁlter, foldl, zipWith, ... we’ve been passing functions everywhere already 1http://www.haskell.org/haskellwiki/Higher_order_function 11 / 12
27. Higher Order Functions Example: :t quEndergebnis > quEndergebnis :: Int

-> [String] -> [[Int]] -> String :t endergebnis > endergebnis :: [String] -> [[Int]] -> String 11 / 12
28. Higher Order Functions Example: :t quEndergebnis > quEndergebnis :: Int

-> [String] -> [[Int]] -> String :t endergebnis > endergebnis :: [String] -> [[Int]] -> String :t (quEndergebnis 50) > (quEndergebnis 50) :: [String] -> [[Int]] -> String 11 / 12
29. Higher Order Functions Example: :t quEndergebnis > quEndergebnis :: Int

-> [String] -> [[Int]] -> String :t endergebnis > endergebnis :: [String] -> [[Int]] -> String :t (quEndergebnis 50) > (quEndergebnis 50) :: [String] -> [[Int]] -> String endergebnis = quEndergebnis 50 11 / 12