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

Lessons learned at Haskell Private

Sponsored · Ship Features Fearlessly Turn features on and off without deploys. Used by thousands of Ruby developers.
Avatar for Jürgen Cito 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

Avatar for Jürgen Cito

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