Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Lessons learned at Haskell Private

Jürgen Cito
December 10, 2013

Lessons learned at Haskell Private

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.

[1] http://www.complang.tuwien.ac.at/knoop/fp185A03_ws1314.html
[2] http://www.tuwien.ac.at

Jürgen Cito

December 10, 2013
Tweet

More Decks by Jürgen Cito

Other Decks in Programming

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 • filter • 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 – filter Retain elements that return true

    on given function, drop all others filter :: (a -> Bool) -> [a] -> [a] 6 / 12
  10. Working with lists – filter 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 – filter 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, filter, 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