Haskell in the Real World

2,690 views
2,571 views

Published on

A short talk on what makes Functional Programming - and especially Haskell - different.

We'll take a quick overview of Haskell's features and coding style, and then work through a short but complete example of using it for a Real World problem.

http://lanyrd.com/2011/geekup-liverpool-may/sdykh/

1 Comment
2 Likes
Statistics
Notes
  • Video at http://vimeo.com/24676617
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here
No Downloads
Views
Total views
2,690
On SlideShare
0
From Embeds
0
Number of Embeds
858
Actions
Shares
0
Downloads
23
Comments
1
Likes
2
Embeds 0
No embeds

No notes for slide

Haskell in the Real World

  1. 1. Haskell in the Real World Functional Programming Night Geekup Liverpool, 31st May, 2011 hakim.cassimally@gmail.comhttp://www.fickr.com/photos/jef_saf/3493852795/
  2. 2. What makes FP different?● MJD quoting Norvig (on Lisp): ● “big, important features, features like frst-class functions, dynamic access to the symbol table, and automatic storage management.”● gluing functions together● declarative
  3. 3. Popular FP languages● Excel● SQL?● Linq (based on Haskells monads)● Lisp → Scheme → Clojure● Strongly Typed FP (Hindley/Milner) ● ML → Ocaml → F# ● Haskell
  4. 4. What makes Haskell different?● Purity● Laziness● High Level● Strong Typing● Memory Managed● Modular● Mathematical rigour ● category theory
  5. 5. Sounds a bit ivory tower?● http://prog21.dadgum.com/31.html ● Q “When will Haskell fnally go mainstream?” ● A “most of it already has.”
  6. 6. Imperative programming● records = [ "one", "two", "three", "four", "five" ] filtered = []; j = 0; for (i = 0; i < length records; i++) { if (records[i] matches “o”) { filtered[j++] = records[i]; } }
  7. 7. Imperative programming● records = [ "one", "two", "three", "four", "five" ] filtered = []; j = 0; for (i = 0; i < length records; i++) { if (records[i] matches “o”) { filtered[j++] = records[i]; } }
  8. 8. Functional version● filtered = filter (=~ “o”) records
  9. 9. Why is this better?● less code. less bugs● no synthetic variables ● i, j, length records● no risk of off-by-one error● intent clear from skimming● intent clear to compiler● parallelize (MapReduce, Hadoop)
  10. 10. Why is this better?● fewer codes. fewer bugs● no synthetic variables ● i, j, length records● no risk of off-by-one error● intent clear from skimming● intent clear to compiler● parallelize (MapReduce, Hadoop)
  11. 11. Your language has this construct● Perl: my @filtered = grep /o/, @records;● .Net: var filtered = from r in records where r.match(o) select r● Ruby: @filtered = @records.grep /o/● Python: filtered = [x for x in records if re.match(o, x)]● etc.
  12. 12. Another example● countCaps = length . filter (isUpper . head) . words > countCaps “Hello there, Fred” 2
  13. 13. Real World Haskell● JSON library● barcode reading● database
  14. 14. Quizzes● important subsystem of Makinis attention management system● real world (has customers, pays wages)● currently written in Perl● could it be ported to Haskell?
  15. 15. Haskell Quiz – proof of concept● full code at: ● https://github.com/ osfameron/geekup-talk-haskell/● overview, to give a favour of programming in Haskell
  16. 16. Modelling the quiz
  17. 17. Modelling the quiz
  18. 18. Modelling the quiz
  19. 19. Modelling the quiz2x
  20. 20. Modelling the quiz
  21. 21. Modelling the quiz1x
  22. 22. Quiz tree data types● Quizzes● Sections ● (randomized sections)● Questions
  23. 23. Quiz data type● data QuizNode = Quiz Name [QuizNode] | Section Name Score [QuizNode] | RandomSection Name Score Choose [QuizNode] | Question Name Score Answer
  24. 24. Quiz data type● data QuizNode = Quiz Name [QuizNode] | Section Name Score [QuizNode] | RandomSection Name Score Choose [QuizNode] | Question Name Score Answer● type Name = String type Score = Int type Choose = Int
  25. 25. Quiz data type● data QuizNode = Quiz Name [QuizNode] | Section Name Score [QuizNode] | RandomSection Name Score Choose [QuizNode] | Question Name Score Answer● data Answer = MultiChoice [BoolAnswer] | StringChoice [String]
  26. 26. Quiz data type● data QuizNode = Quiz Name [QuizNode] | Section Name Score [QuizNode] | RandomSection Name Score Choose [QuizNode] | Question Name Score Answer● data Answer = MultiChoice [BoolAnswer] | StringChoice [String]● data BoolAnswer = BoolAnswer Bool String
  27. 27. Quiz data typequiz,geo,pop :: QuizNodequiz = Quiz “General Knowledge Quiz” [ pop, geo ]geo = RandomSection “Geography” 40 2 [ Question “What is the capital of England?” 2 $ StringChoice [“London”], Question “What is the capital of France?” 2 $ StringChoice [“Paris”], Question “What is the capital of Finland?” 2 $ StringChoice [“Helsinki”], Question “What is the capital of Italy?” 2 $ StringChoice [“Rome”, “Roma”], ]
  28. 28. Quiz data typequiz,geo,pop :: QuizNodequiz = Quiz “General Knowledge Quiz” [ pop, geo ]geo = RandomSection “Geography” 40 2 [ Question “What is the capital of England?” 2 $ StringChoice [“London”], Question “What is the capital of France?” 2 $ StringChoice [“Paris”], Question “What is the capital of Finland?” 2 $ StringChoice [“Helsinki”], Question “What is the capital of Italy?” 2 $ StringChoice [“Rome”, “Roma”], ]
  29. 29. Quiz data typequiz,geo,pop :: QuizNodequiz = Quiz “General Knowledge Quiz” [ pop, geo ]geo = RandomSection “Geography” 40 2 [ Question “What is the capital of England?” 2 $ StringChoice [“London”], Question “What is the capital of France?” 2 $ StringChoice [“Paris”], Question “What is the capital of Finland?” 2 $ StringChoice [“Helsinki”], Question “What is the capital of Italy?” 2 $ StringChoice [“Rome”, “Roma”], ]
  30. 30. Quiz data typepop = Section “Pop music” 60 [ Question “Which of these are Beatles?” 5 $ MultiChoice [ y “John”, y “Paul”, y “George”, y “Ringo”, n “Bob”, n “Jason” ], ...
  31. 31. Quiz data typepop = Section “Pop music” 60 [ Question “Which of these are Beatles?” 5 $ MultiChoice [ BoolAnswer True “John”, BoolAnswer True “Paul”, BoolAnswer True “George”, BoolAnswer True “Ringo”, BoolAnswer False “Bob”, BoolAnswer False “Jason” ], ...
  32. 32. Quiz data typepop = Section “Pop music” 60 [ Question “Which of these are Beatles?” 5 $ MultiChoice [ y “John”, y “Paul”, y “George”, y “Ringo”, n “Bob”, n “Jason” ], ...y,n :: String -> BoolAnswery = BoolAnswer Truen = BoolAnswer False
  33. 33. Stamping the quiz1x 2x
  34. 34. Stamping the quiz1x 2x
  35. 35. Stamping the quiz stamp :: QuizNode → ...1x 2x
  36. 36. Stamping the quiz stamp :: QuizNode → QuizNode?1x 2x
  37. 37. Functions● increment :: Num → Num ● increment 4 => 5 ● increment 10 => 11
  38. 38. Functions● increment :: Num → Num ● increment 4 => 5 ● increment 10 => 11
  39. 39. Functions● increment :: Num → Num ● increment 4 => 5 ● increment 10 => 11
  40. 40. Functions● increment :: Num → Num● increment x = x+1
  41. 41. Functionslet x = 42 addx :: Num → Num add y = x + y
  42. 42. Functions (cannotlet x = 42 change!) addx :: Num → Num add y = x + y
  43. 43. Functionslet x = 42 addx :: Num → Num add y = x + y
  44. 44. Stamping the quiz stamp :: QuizNode → QuizNode?1x 2x
  45. 45. Stamping the quiz stamp :: QuizNode → QuizNode?1x 2x
  46. 46. Stamping the quiz stamp :: QuizNode → IO QuizNode1x 2x
  47. 47. Monads● Useful data-structure● Lets us model various thing... ● including IO in a pure language● Concept is a little confusing● Using them is (mostly) not too bad.
  48. 48. Stamping the quiz stamp :: QuizNode → IO QuizNode
  49. 49. Stamping the quiz stamp :: QuizNode → IO QuizNode1x 2x
  50. 50. Stamping the quiz stamp :: QuizNode → IO QuizNode1x 2x
  51. 51. Stamping the quiz stamp :: QuizNode → IO QuizNode
  52. 52. Stamping the quiz stamp :: QuizNode → IO QuizNode
  53. 53. The stamp functionstamp :: QuizNode -> IO QuizNodestamp q@(Question _ _ _) = return qstamp (Quiz s ns) = Quiz s <$> mapM stamp nsstamp (Section s i ns) = Section s i <$> mapM stamp nsstamp (RandomSection s i r ns) = do selected <- pickN r ns Section s i <$> mapM stamp selected
  54. 54. The stamp functionstamp :: QuizNode -> IO QuizNodestamp q@(Question _ _ _) = return qstamp (Quiz s ns) = Quiz s <$> mapM stamp nsstamp (Section s i ns) = Section s i <$> mapM stamp nsstamp (RandomSection s i r ns) = do selected <- pickN r ns Section s i <$> mapM stamp selected
  55. 55. The stamp function map stamp nsstamp :: QuizNode -> IO QuizNode – “stamp all the child nodes instamp q@(Question _ _ _) = return q turn”stamp (Quiz s ns) = Quiz s <$> mapM stamp nsstamp (Section s i ns) = Section s i <$> mapM stamp nsstamp (RandomSection s i r ns) = do selected <- pickN r ns Section s i <$> mapM stamp selected
  56. 56. The stamp functionstamp :: QuizNode -> IO QuizNodestamp q@(Question _ _ _) = return qstamp (Quiz s ns) = Quiz s <$> mapM stamp nsstamp (Section s i ns) = Section s i <$> mapM stamp nsstamp (RandomSection s i r ns) = do selected <- pickN r ns Section s i <$> mapM stamp selected
  57. 57. The stamp functionstamp :: QuizNode -> IO QuizNodestamp q@(Question _ _ _) = return qstamp (Quiz s ns) = Quiz s <$> mapM stamp nsstamp (Section s i ns) = Section s i <$> mapM stamp nsstamp (RandomSection s i r ns) = do selected <- pickN r ns Section s i <$> mapM stamp selected1x
  58. 58. Taking the quiz!● takeNode :: QuizNode -> IO CompletedNode● printQuestion :: QuizNode -> IO ()● showBoolTextAnswers :: [BoolAnswer] -> String● checkAnswer :: String -> Answer -> Bool
  59. 59. Taking the quiz!● takeNode :: QuizNode -> IO CompletedNode● printQuestion :: QuizNode -> IO ()● showBoolTextAnswers :: [BoolAnswer] -> String● checkAnswer :: String -> Answer -> Bool
  60. 60. Taking the quiz!● takeNode :: QuizNode -> IO CompletedNode● printQuestion :: QuizNode -> IO ()● showBoolTextAnswers :: [BoolAnswer] -> String● checkAnswer :: String -> Answer -> Bool
  61. 61. Taking the quiz!● takeNode :: QuizNode -> IO CompletedNode● printQuestion :: QuizNode -> IO ()● showBoolTextAnswers :: [BoolAnswer] -> String● checkAnswer :: String -> Answer -> Bool
  62. 62. takeNodetakeNode node@(Question s i a) = do printQuestion node ans <- getLine let correct = checkAnswer ans a let score = if correct then (i,i) else (0,i) putStrLn $ if correct then “Correct!” else “Wrong!” return $ CompletedNode ans score [] node
  63. 63. mainmain :: IO ()main = stamp quiz >>= takeQuiz Function, not entrypoint
  64. 64. mainmain :: IO ()main = stamp quiz >>= takeQuiz Live Demo!
  65. 65. Should you go Haskell?● Power● Speed? ● can be faster than C (supercompilation) ● can be tricky to optimize● Jobs? ● In NorthWestUK?● Libraries & Tools ● Haskell Platform. Hackage. Cabal
  66. 66. Should you learn Haskell?● Powerful● Interesting techniques● … and ways of thinking about problems● Ready for future shift to FP● … possibly in your own language
  67. 67. Thank you! Questions? ● full code at: ● https://github.com/ osfameron/geekup-talk-haskell/ ● hakim.cassimally@gmail.comhttp://www.fickr.com/photos/jef_saf/3493852795/

×