Haskell Tour (Part 1)

4,987 views

Published on

We introduce Haskell. Why is it interesting. Where did it come from. What is it like. How to get started.

We show a GHCi session. We introduce simple recursive function and data. And we demo QuickCheck for testing properties of automatically generated data.

Published in: Technology, Education
0 Comments
11 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
4,987
On SlideShare
0
From Embeds
0
Number of Embeds
899
Actions
Shares
0
Downloads
132
Comments
0
Likes
11
Embeds 0
No embeds

No notes for slide

Haskell Tour (Part 1)

  1. 1. HaskellA Whirlwind Tour William Taysom 2011
  2. 2. Haskell
  3. 3. HaskellWho?What?When?Where?Why?How?
  4. 4. HaskellWho?What?When?Where?Why?How?
  5. 5. Why? Aesthetics
  6. 6. Why? Aesthetics“We provided DARPA with a copy of our prototypeimplemented in Haskell without explaining that it wasa program, and based on preconceptions from theirpast experience, they had studied the program underthe assumption that it was a mixture of requirementsspecification and top level design. They wereconvinced it was incomplete because it did not addressissues such as data structure design and executionorder.” — Paul Hudak
  7. 7. Why? Aesthetics“Take Lisp: you know its the most beautiful languagein the world. At least up until Haskell came along.” — Larry Wall
  8. 8. Why? Aesthetics“Reading Haskell is like reading poetry.Writing Haskell is like writing poetry.” — Oliver Steele
  9. 9. Why? Aesthetics“I also have interest in Haskell, but my brain justexplodes every time I read a Haskell program biggerthan ten lines.” — Matz
  10. 10. Why? Aesthetics“The biggest advantage of Haskell to me is that it helpsme write better programs in other languages.” — Tenerife Skunkworks
  11. 11. Why? Aesthetics.NET LINQPython List ComprehensionsJava GenericsJavaScript jQuery
  12. 12. Why? Pragmatics
  13. 13. Why? PragmaticsPlatform Compiler Debugger Profiler TestingLibraries Network Graphics HackageCommunity Books Documentation Hoogle
  14. 14. Why? PragmaticsPlatform Compiler Debugger Profiler TestingLibraries Network Graphics HackageCommunity Books Documentation Hoogle
  15. 15. Why? Pragmatics Hoogle
  16. 16. Why? Pragmatics Hoogle
  17. 17. Why? PragmaticsPlatform Compiler Debugger Profiler TestingLibraries Network Graphics HackageCommunity Books Documentation Hoogle
  18. 18. Why? PragmaticsPlatform Compiler Debugger Profiler TestingLibraries Network Graphics HackageCommunity Books Documentation Hoogle
  19. 19. How? GHC Documentation Libraries Cabal Hackage
  20. 20. Why? PragmaticsPlatform Compiler Debugger Profiler TestingLibraries Network Graphics HackageCommunity Books Documentation Hoogle
  21. 21. Why? Pragmatics
  22. 22. Why? Pragmatics
  23. 23. Why? Pragmatics“A programming language must be considered in thecontext of its community, and Haskell has anexemplary one. I have come to believe, however, thatthis polite exterior conceals a deep and consumingmadness.” — Avdi Grimm
  24. 24. Why? Performance
  25. 25. Why? PerformanceThe Computer Language Benchmarks Game
  26. 26. Why? Performance Web Server Pong benchmark, extra large instance, requests/second
  27. 27. Why? Performance Web Server Pong benchmark, extra large instance, requests/second
  28. 28. Why? Aesthetics Pragmatics Performance
  29. 29. HaskellWho?What?When?Where?Why? Aesthetics Pragmatics PerformanceHow?
  30. 30. HaskellWho?What?When?Where?Why? Aesthetics Pragmatics PerformanceHow?
  31. 31. Who? When? Where? September 1987
  32. 32. Who? When? Where? Portland, Oregon
  33. 33. Who? When? Where?Functional ProgrammingLanguages and ComputerArchitecture Conference
  34. 34. Who? When? Where? A Dozen Purely Functional Languages
  35. 35. Who? When? Where? All Similar
  36. 36. Who? When? Where? Committee Formed
  37. 37. Who? When? Where? Committee Formed
  38. 38. Provide faster communication of newideas.Stable foundation for real applicationdevelopment.Vehicle through which others would beencouraged to use functional languages.
  39. 39. Who? When? Where?Haskell ReportApril 1st 1990“You know, Haskellactually never liked thename Haskell.” — Mary Curry
  40. 40. Who? When? Where? 2002Revised Haskell 98 Report
  41. 41. Who? When? Where? 2010 Haskell
  42. 42. HaskellWho? Research Wadler Hudak Peyton-JonesWhat?When? 1987 1990 2002 NowWhere? Portland Glasgow MicrosoftWhy? Aesthetics Pragmatics PerformanceHow?
  43. 43. HaskellWho? Research Wadler Hudak Peyton-JonesWhat?When? 1987 1990 2002 NowWhere? Portland Glasgow MicrosoftWhy? Aesthetics Pragmatics PerformanceHow?
  44. 44. What?A non-strict, purelyfunctional programminglanguage with strong,static type inference.
  45. 45. What?A non-strict, purelyfunctional programminglanguage with strong,static type inference.
  46. 46. What? ProgrammingSource CodeFormal, Textural SyntaxStatic & Runtime SemanticsData, Variables, Lexical ScopeInterpreter, Compiler
  47. 47. What?A non-strict, purelyfunctional programminglanguage with strong,static type inference.
  48. 48. What?A non-strict, purelyfunctional programminglanguage with strong,static type inference.
  49. 49. What? Functional (Not Imperative)
  50. 50. What? FunctionalImperative Statements Executed Step-by-step
  51. 51. What? FunctionalImperative Statements Executed Step-by-step Modifying State
  52. 52. What? FunctionalImperative Statements Executed Step-by-step Modifying State Turing Machine
  53. 53. What? FunctionalImperative Statements Executed Step-by-step Modifying State Von Neumann Architecture
  54. 54. What? FunctionalImperative Statements Executed Step-by-step Modifying State Von Neumann ArchitectureFunctional Expressions Recursively Simplified
  55. 55. What? FunctionalImperative Statements Executed Step-by-step Modifying State Von Neumann ArchitectureFunctional Expressions Recursively Simplified Reduced Value
  56. 56. What? FunctionalImperative Statements Executed Step-by-step Modifying State Von Neumann ArchitectureFunctional Expressions Recursively Simplified Reduced Value Lambda Calculus
  57. 57. What? FunctionalImperative Statements Executed Step-by-step Modifying State Von Neumann ArchitectureFunctional Expressions Recursively Simplified Reduced Value Lambda Calculus
  58. 58. What? FunctionalImperative Statements Executed Step-by-step Modifying State Von Neumann ArchitectureFunctional Expressions Recursively Simplified Reduced Value Lambda Calculus
  59. 59. What?A non-strict, purelyfunctional programminglanguage with strong,static type inference.
  60. 60. What?A non-strict, purelyfunctional programminglanguage with strong,static type inference.
  61. 61. What? Pure (No Side Effects)
  62. 62. What? Pure Immutable Only
  63. 63. What? PureReferential Transparency
  64. 64. What? Pure Functions always return the same value. If v = f x, then you can always replace f x with v.
  65. 65. What? Pure Functions always return the same value. If v equals f x, then you can always replace f x with v.
  66. 66. What?A non-strict, purelyfunctional programminglanguage with strong,static type inference.
  67. 67. What?A non-strict, purelyfunctional programminglanguage with strong,static type inference.
  68. 68. What? Non-strict Be lazy.
  69. 69. What? Non-strict Be lazy. Ignore evaluation order.
  70. 70. Wait...
  71. 71. if everything isimmutable and there are no side effectsand evaluation is lazy,
  72. 72. then how the hell do you do anything?
  73. 73. MONADS Bring your own Semicolon
  74. 74. What? Monads
  75. 75. What? Monads
  76. 76. What? Monads
  77. 77. What? Monads
  78. 78. What? Monads
  79. 79. What? Monads“Haskell is the worlds finestimperative programming language.” — Simon Peyton-Jones
  80. 80. What? Monads“Haskell is the only language I know withfirst-class support for imperative programming.” — SamB
  81. 81. What? Monads“Haskell has no preferred imperative semantics, andthe monad just lets you swap out the semanticsaccording to your needs.” — Jared Updike
  82. 82. What?A non-strict, purelyfunctional programminglanguage with strong,static type inference.
  83. 83. What?A non-strict, purelyfunctional programminglanguage with strong,static type inference.
  84. 84. What? Types Strong Static Inference
  85. 85. What? Types Strong Static Inference
  86. 86. What? Strong Types Runtime values have types.
  87. 87. What? Strong Types Runtime values have types. like Java and Ruby unlike C and Assembly (Not Weak)
  88. 88. What? Types Strong Static Inference
  89. 89. What? Types Strong Static Inference
  90. 90. What? Static Types Source code expressions have types.
  91. 91. What? Static Types Source code expressions have types. like C and Java unlike Ruby and JavaScript (Not Dynamic)
  92. 92. What? Types Strong Static Inference
  93. 93. What? Types Strong Static Inference
  94. 94. What? Type InferenceAutomatically determines types of variables.
  95. 95. What? Type InferenceAutomatically determines types of variables. like C# and Go unlike C and Java (Not Manifest)
  96. 96. You don’t need to type the type!
  97. 97. SYNERGY Purity means types tell you a lot.
  98. 98. What? Type Purity No side effects mean,
  99. 99. What? Type Purity No side effects mean, argument and return types limit what a function can do.
  100. 100. What? Type Purity“Haskell is so strict about type safety that randomlygenerated snippets of code that successfully type checkare likely to do something useful, even if youve no ideawhat that useful thing is.” — sigfpe
  101. 101. What? Type Purity“Since when does "it compiles" equate to "it will run(correctly)"? Were talking about C, after all, notHaskell.” — Sean Russell
  102. 102. What? Types Strong Static Inference
  103. 103. What?A non-strict, purelyfunctional programminglanguage with strong,static type inference.
  104. 104. What?A non-strict, purelyfunctional programminglanguage with strong,static type inference.
  105. 105. HaskellWho? Research Wadler Hudak Peyton-JonesWhat? Non-strict Purely Functional Static TypesWhen? 1987 1990 2002 NowWhere? Portland Glasgow MicrosoftWhy? Aesthetics Pragmatics PerformanceHow?
  106. 106. HaskellWho? Research Wadler Hudak Peyton-JonesWhat? Non-strict Purely Functional Static TypesWhen? 1987 1990 2002 NowWhere? Portland Glasgow MicrosoftWhy? Aesthetics Pragmatics PerformanceHow?
  107. 107. How? Just Download and Install the Platform
  108. 108. How? Just Download and Install the Platform
  109. 109. Glorious GlasgowHaskell Compilation System
  110. 110. GHCCompiler ghcInteractive ghciScripts runghc
  111. 111. GHCCompiler ghcInteractive ghciScripts runghc
  112. 112. HaskellWho? Research Wadler Hudak Peyton-JonesWhat? Non-strict Purely Functional Static TypesWhen? 1987 1990 2002 NowWhere? Portland Glasgow MicrosoftWhy? Aesthetics Pragmatics PerformanceHow? Platform Hoogle Hackage
  113. 113. HaskellWho? Research Wadler Hudak Peyton-JonesWhat? Non-strict Purely Functional Static TypesWhen? 1987 1990 2002 NowWhere? Portland Glasgow MicrosoftWhy? Aesthetics Pragmatics PerformanceHow? Platform Hoogle Hackage
  114. 114. Example
  115. 115. ┼ $ Example
  116. 116. $ ghci
  117. 117. $ ghciGHCi, version 7.0.2: http://www.haskell.org/ghc/ :? for helpLoading package ghc-prim ... linking ...done.Loading package integer-gmp ...linking ... done.Loading package base ... linking ...done.Loading package ffi-1.0 ... linking ...done.ghci>
  118. 118. $ ghciGHCi, version 7.0.2: http://www.haskell.org/ghc/ :? for helpLoading package ghc-prim ... linking ...done.Loading package integer-gmp ...linking ... done.Loading package base ... linking ...done.Loading package ffi-1.0 ... linking ...done.ghci> "hello, world"
  119. 119. $ ghciGHCi, version 7.0.2: http://www.haskell.org/ghc/ :? for helpLoading package ghc-prim ... linking ...done.Loading package integer-gmp ...linking ... done.Loading package base ... linking ...done.Loading package ffi-1.0 ... linking ...done.ghci> "hello, world""hello, world"ghci>
  120. 120. "hello, world"ghci>
  121. 121. "hello, world"ghci> 6 * 9
  122. 122. "hello, world"ghci> 6 * 942ghci>
  123. 123. "hello, world"ghci> 6 * 942ghci> [1, 2, 3]
  124. 124. "hello, world"ghci> 6 * 942ghci> [1, 2, 3][1,2,3]ghci>
  125. 125. "hello, world"ghci> 6 * 942ghci> [1, 2, 3][1,2,3]ghci> it
  126. 126. "hello, world"ghci> 6 * 942ghci> [1, 2, 3][1,2,3]ghci> it[1,2,3]ghci>
  127. 127. "hello, world"ghci> 6 * 942ghci> [1, 2, 3][1,2,3] application is so important in Haskell that “Functionghci> it it using the quietest possible syntax: we denote[1,2,3]at all.” nothingghci> reverse it — Simon Peyton-Jones
  128. 128. “Function application is so important in Haskell thatwe denote it using the quietest possible syntax:nothing at all.” — Simon Peyton-Jones
  129. 129. "hello, world"ghci> 6 * 942ghci> [1, 2, 3][1,2,3] application is so important in Haskell that “Functionghci> it it using the quietest possible syntax: we denote[1,2,3]at all.” nothingghci> reverse it — Simon Peyton-Jones
  130. 130. "hello, world"ghci> 6 * 942ghci> [1, 2, 3][1,2,3]ghci> it[1,2,3]ghci> reverse it[3,2,1]ghci>
  131. 131. [3,2,1]ghci>
  132. 132. [3,2,1]ghci> let xs = [1..100]
  133. 133. [3,2,1]ghci> let xs = [1..100]ghci>
  134. 134. [3,2,1]ghci> let xs = [1..100]ghci> xs
  135. 135. [3,2,1]ghci> let xs = [1..100]ghci> xs[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100]ghci>
  136. 136. [3,2,1]ghci> let xs = [1..100]ghci> xs[1,2,⋯,99,100]ghci>
  137. 137. [3,2,1]ghci> let xs = [1..100]ghci> xs[1,2,⋯,99,100]ghci> [x | x <- xs, x > 21]
  138. 138. [3,2,1]ghci> let xs = [1..100]ghci> xs[1,2,⋯,99,100]ghci> [x | x <- xs, x > 21][22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100]ghci>
  139. 139. [3,2,1]ghci> let xs = [1..100]ghci> xs[1,2,⋯,99,100]ghci> [x | x <- xs, x > 21][22,23,⋯,99,100]ghci>
  140. 140. [3,2,1]ghci> let xs = [1..100]ghci> xs[1,2,⋯,99,100]ghci> [x | x <- xs, x > 21][22,23,⋯,99,100]ghci> filter (> 21) xs
  141. 141. [3,2,1]ghci> let xs = [1..100]ghci> xs[1,2,⋯,99,100]ghci> [x | x <- xs, x > 21][22,23,⋯,99,100]ghci> filter (> 21) xs[22,23,⋯,99,100]ghci>
  142. 142. [3,2,1]ghci> let xs = [1..100]ghci> xs[1,2,⋯,99,100]ghci> [x | x <- xs, x > 21][22,23,⋯,99,100]ghci> filter (> 21) xs[22,23,⋯,99,100]ghci> filter (x -> x > 21) xs
  143. 143. [3,2,1]ghci> let xs = [1..100]ghci> xs[1,2,⋯,99,100]ghci> [x | x <- xs, x > 21][22,23,⋯,99,100] TMTOWTDIghci> filter (> 21) xs[22,23,⋯,99,100]ghci> filter (x -> x > 21) xs[22,23,⋯,99,100]ghci>
  144. 144. TMTOWTDI
  145. 145. The Evolution of aHaskell Programmer1. Freshman 13. Continuation-passing2. Sophomore 14. Boy Scout3. Junior (Peano) 15. Combinatory4. Junior (Ban n+k) 16. List-encoding5. Senior (Leans Right) 17. Interpretive6. Senior (Leans Left) 18. Static7. Senior (Leans Around) 19. Beginning Graduate8. Memoizing 20. Origamist9. Points-free 21. Cartesianally-inclined10. Iterative 22. Ph.D.11. Iterative one-liner 23. Post-doc12. Accumulating 24. Tenured Professor
  146. 146. TMTOWTDI
  147. 147. [3,2,1]ghci> let xs = [1..100]ghci> xs[1,2,⋯,99,100]ghci> [x | x <- xs, x > 21][22,23,⋯,99,100] TMTOWTDIghci> filter (> 21) xs[22,23,⋯,99,100]ghci> filter (x -> x > 21) xs[22,23,⋯,99,100]ghci>
  148. 148. [22,23,⋯,99,100]ghci>
  149. 149. [22,23,⋯,99,100]ghci> let divides = x y -> rem y x == 0
  150. 150. [22,23,⋯,99,100]ghci> let divides = x y -> rem y x == 0ghci>
  151. 151. [22,23,⋯,99,100]ghci> let divides = x y -> rem y x == 0ghci> let divides x y = rem y x == 0
  152. 152. [22,23,⋯,99,100]ghci> let divides = x y -> rem y x == 0ghci> let divides x y = rem y x == 0ghci>
  153. 153. [22,23,⋯,99,100]ghci> let divides = x y -> rem y x == 0ghci> let divides x y = rem y x == 0ghci> divides 3 12
  154. 154. [22,23,⋯,99,100]ghci> let divides = x y -> rem y x == 0ghci> let divides x y = rem y x == 0ghci> divides 3 12Trueghci>
  155. 155. [22,23,⋯,99,100]ghci> let divides = x y -> rem y x == 0ghci> let divides x y = rem y x == 0ghci> divides 3 12Trueghci> 3 `divides` 12
  156. 156. [22,23,⋯,99,100]ghci> let divides = x y -> rem y x == 0ghci> let divides x y = rem y x == 0ghci> divides 3 12Trueghci> 3 `divides` 12Trueghci>
  157. 157. [22,23,⋯,99,100]ghci> let divides = x y -> rem y x == 0ghci> let divides x y = rem y x == 0ghci> divides 3 12Trueghci> 3 `divides` 12Trueghci> let divisors x = [d | d <- [1..x],d `divides` x]
  158. 158. [22,23,⋯,99,100]ghci> let divides = x y -> rem y x == 0ghci> let divides x y = rem y x == 0ghci> divides 3 12Trueghci> 3 `divides` 12Trueghci> let divisors x = [d | d <- [1..x],d `divides` x]ghci>
  159. 159. [22,23,⋯,99,100]ghci> let divides = x y -> rem y x == 0ghci> let divides x y = rem y x == 0ghci> divides 3 12Trueghci> 3 `divides` 12Trueghci> let divisors x = [d | d <- [1..x],d `divides` x]ghci> divisors 100
  160. 160. [22,23,⋯,99,100]ghci> let divides = x y -> rem y x == 0ghci> let divides x y = rem y x == 0ghci> divides 3 12Trueghci> 3 `divides` 12True Fundamentalsghci> let divisors x = [d | d <- [1..x],d `divides` x]ghci> divisors 100[1,2,4,5,10,20,25,50,100]ghci>
  161. 161. Fundamentals
  162. 162. Data Declarationdata Color = Red | Green | Blue
  163. 163. Variablesred = Red-- Lower case for variable and upper case forconstructor.nan = 0 / 0-- Variables stand for values. They do not labellocations.-- Dont need let because we arent at GHCi.-- Declarations go at top-level, not expressions.(Like Java, unlike Ruby.)
  164. 164. Functionshue Red = 0hue Green = 120hue Blue = 240
  165. 165. Lambda & Casehue = c -> case c of Red -> 0 Green -> 120 Blue -> 240
  166. 166. Pattern WildcardisRed Red = TrueisRed _ = False
  167. 167. Boolean Datadata Bool = True | False
  168. 168. Boolean Functionsotherwise = Truenot True = Falsenot False = True
  169. 169. Boolean OperatorsTrue && x = xFalse && _ = False(||) True _ = True(||) False x = x-- Parenthesis let us use operators prefix.
  170. 170. Operator Precedenceinfixr 3 &&infixr 2 ||-- Ten precedence levels: 0 binds least tightly, 9(default) binds most tightly.-- Three associativities: infixl (default), infixr,infix (non-associative).
  171. 171. Types“Types in Haskell express high-level design in the sameway that UML diagrams do in Object Orientedlanguages.” — Simon Peyton-Jones
  172. 172. Typesghci> :l example“Types in Haskell express high-level design in the sameway that UML diagrams do in Object Orientedlanguages.” — Simon Peyton-Jones
  173. 173. ghci> :l example[1 of 1] Compiling Main( example.hs, interpreted )Ok, modules loaded: Main.ghci>
  174. 174. ghci> :l example[1 of 1] Compiling Main( example.hs, interpreted )Ok, modules loaded: Main.ghci> :r
  175. 175. ghci> :l example[1 of 1] Compiling Main( example.hs, interpreted )Ok, modules loaded: Main.ghci> :rOk, modules loaded: Main.ghci>
  176. 176. ghci> :l example[1 of 1] Compiling Main( example.hs, interpreted )Ok, modules loaded: Main.ghci> :rOk, modules loaded: Main.ghci> :type red
  177. 177. ghci> :l example[1 of 1] Compiling Main( example.hs, interpreted )Ok, modules loaded: Main.ghci> :rOk, modules loaded: Main.ghci> :type redRed :: Colorghci>
  178. 178. ghci> :l example[1 of 1] Compiling Main( example.hs, interpreted )Ok, modules loaded: Main.ghci> :rOk, modules loaded: Main.ghci> :type redRed :: Colorghci> :t isRed
  179. 179. Typesghci> :l example[1 of 1] Compiling Main( example.hs, interpreted )Ok, :: Color loaded: Main. red modulesghci> Double nan :: :rOk, modules loaded: Main.ghci> Color -> Double hue :: :type redRed :: Color otherwise :: Boolghci> :t isRedisRed Bool -> Bool Bool not :: :: Color ->ghci> (||) :: Bool -> Bool -> Bool (&&),
  180. 180. Typesred :: Colornan :: Doublehue :: Color -> Doubleotherwise :: Boolnot :: Bool -> Bool(&&), (||) :: Bool -> Bool -> Bool
  181. 181. Recursive Datadata Color = Red | Green | Blue | Mix Color Color
  182. 182. Recursive Datadata Color = Red | Green | Blue | Mix Color Colormix :: Color -> Color -> Colormix = Mix-- Mix is a type constructor function.
  183. 183. Recursive Datayellow, cyan, magenta :: Coloryellow = Mix Red GreenMix cyan magenta = Mix (Mix Green Blue) (Mix Red Blue)-- Constructor functions can be used for patternmatching, but variables bind.
  184. 184. Recursive FunctionsisRed :: Color -> BoolisRed Red = TrueisRed (Mix c c) = isRed c && isRed cisRed _ = False
  185. 185. Recursive Functionshue :: Color -> Doublehue Red =0hue Green = 120hue Blue = 240
  186. 186. Recursive Functionshue :: Color -> Doublehue Red =0hue Green = 120hue Blue = 240hue (Mix c c) = ???
  187. 187. hue (Mix c c) = ???
  188. 188. hue (Mix c c) = ??? h
  189. 189. hue (Mix c c) = let h = hue c ??? h
  190. 190. hhue (Mix c c) = let h = hue c ??? h
  191. 191. hhue (Mix c c) = let h = hue c h = hue c ??? h
  192. 192. h mhue (Mix c c) = let h = hue c h = hue c ??? h
  193. 193. h mhue (Mix c c) = let h = hue c h = hue c m = average h h h ???
  194. 194. h mhue (Mix c c) = let h = hue c h = hue c m = average h h h average x y = abs (x + y) / 2 ???
  195. 195. h mhue (Mix c c) = let h = hue c h = hue c m = average h h h average x y = abs (x + y) / 2 in m
  196. 196. h mhue (Mix c c) = let h = hue c h = hue c m = average h h h average x y = abs (x + y) / 2 in ??!
  197. 197. mhue (Mix c c) = let h = hue c h = hue c m = average h h h average x y = abs (x + y) / 2 in ??! h
  198. 198. mhue (Mix c c) = let h = hue c h = hue c m = average h h h average x y = abs (x + y) / 2 in ??! h m
  199. 199. mhue (Mix c c) = let h = hue c h = hue c m = average h h h m = m + 180 average x y = abs (x + y) / 2 in ??! h m
  200. 200. m dhue (Mix c c) = let h = hue c h = hue c m = average h h h m = m + 180 average x y = abs (x + y) / 2 in ??! h m
  201. 201. m dhue (Mix c c) = let h = hue c h = hue c m = average h h h m = m + 180 d = distance h m average x y = abs (x + y) / 2 in ??! h m
  202. 202. m dhue (Mix c c) = let h = hue c h = hue c m = average h h h m = m + 180 d = distance h m average x y = abs (x + y) / 2 distance x y = abs (x - y) h m in ??!
  203. 203. m dhue (Mix c c) = let h = hue c h = hue c m = average h h h m = m + 180 d = distance h m average x y = abs (x + y) / 2 distance x y = abs (x - y) h m in case compare d 90 of LT -> m EQ -> ??! GT -> m
  204. 204. m dhue (Mix c c) = let h = hue c h = hue c m = average h h h m = m + 180 d = distance h m average x y = abs (x + y) / 2 distance x y = abs (x - y) h m in case compare d 90 of LT -> m EQ -> nan GT -> m
  205. 205. m dhue (Mix c c) = r where r = case compare d 90 of LT -> m EQ -> nan h GT -> m h = hue c h = hue c m = average h h m = m + 180 h m d = distance h maverage x y = abs (x + y) / 2distance x y = abs (x - y)
  206. 206. Testingtest-framework organize testsHUnit what you’re used toQuickCheck test properties with automatically generated data
  207. 207. QuickCheckprop_hue_bounds c = let h = hue c in isNaN h || 0 <= h && h < 360
  208. 208. QuickCheckprop_hue_bounds c = let h = hue c in isNaN h || 0 <= h && h < 360prop_hue_mix_reflexivity c = let h = hue c in isNaN h || hue (Mix c c) == h
  209. 209. QuickCheckprop_hue_bounds c = let h = hue c in isNaN h || 0 <= h && h < 360prop_hue_mix_reflexivity c = let h = hue c in isNaN h || hue (Mix c c) == hprop_hue_mix_commutativity c c = let h = hue (Mix c c) in isNaN h || hue (Mix c c) == h
  210. 210. QuickCheckghci> quickCheck prop_hue_mix_commutativityprop_hue_bounds c = let h = hue c in isNaN h || 0 <= h && h < 360prop_hue_mix_reflexivity c = let h = hue c in isNaN h || hue (Mix c c) == hprop_hue_mix_commutativity c c = let h = hue (Mix c c) in isNaN h || hue (Mix c c) == h
  211. 211. ghci> quickCheck prop_hue_mix_commutativity+++ OK, passed 100 tests.ghci>
  212. 212. ghci> quickCheck prop_hue_mix_commutativity+++ OK, passed 100 tests.ghci> quickCheck prop_hue_mix_reflexivity
  213. 213. ghci> quickCheck prop_hue_mix_commutativity+++ OK, passed 100 tests.ghci> quickCheck prop_hue_mix_reflexivity+++ OK, passed 100 tests.ghci>
  214. 214. ghci> quickCheck prop_hue_mix_commutativity+++ OK, passed 100 tests.ghci> quickCheck prop_hue_mix_reflexivity+++ OK, passed 100 tests.ghci> quickCheck prop_hue_bounds
  215. 215. ghci> quickCheck prop_hue_mix_commutativity+++ OK, passed 100 tests.ghci> quickCheck prop_hue_mix_reflexivity+++ OK, passed 100 tests.ghci> quickCheck prop_hue_bounds*** Failed! Falsifiable (after 3 tests):Mix (Mix Red Blue) (Mix Green Red)ghci>
  216. 216. ghci> quickCheck prop_hue_mix_commutativity+++ OK, passed 100 tests.ghci> quickCheck prop_hue_mix_reflexivity+++ OK, passed 100 tests.ghci> quickCheck prop_hue_bounds*** Failed! Falsifiable (after 3 tests):Mix (Mix Red Blue) (Mix Green Red)ghci> hue (Mix magenta yellow)
  217. 217. ghci> quickCheck prop_hue_mix_commutativity+++ OK, passed 100 tests.ghci> quickCheck prop_hue_mix_reflexivity+++ OK, passed 100 tests.ghci> quickCheck prop_hue_bounds*** Failed! Falsifiable (after 3 tests):Mix (Mix Red Blue) (Mix Green Red)ghci> hue (Mix magenta yellow)360.0ghci>
  218. 218. hhue (Mix c c) = r where r = case compare d 90 of LT -> m EQ -> nan m m GT -> m h = hue c h = hue c m = average h h d h m = m + 180 d = distance h m
  219. 219. hhue (Mix c c) = r where r = case compare d 90 of LT -> m EQ -> nan m m GT -> m h = hue c h = hue c m = average h h d h m = normalize (m + 180) d = distance h m
  220. 220. hhue (Mix c c) = r where r = case compare d 90 of LT -> m EQ -> nan m m GT -> m h = hue c h = hue c m = average h h d h m = normalize (m + 180) d = distance h mnormalize h | h < 360 = h | otherwise = h - 360
  221. 221. hhue (Mix c c) = r where r = case compare d 90 of LT -> m EQ -> nan m m GT -> m h = hue c h = hue c m = average h h d h m = normalize (m + 180) d = distance h mnormalize h | h < 360 = h | otherwise = normalize (h - 360)
  222. 222. ghci> h hue (Mix c c) = r where r = case compare d 90 of LT -> m EQ -> nan m m GT -> m h = hue c h = hue c m = average h h d h m = normalize (m + 180) d = distance h mnormalize h | h < 360 = h | otherwise = normalize (h - 360)
  223. 223. ghci> quickCheck prop_hue_bounds m
  224. 224. ghci> quickCheck prop_hue_bounds+++ OK, passed 100 tests.ghci> m
  225. 225. QuickCheckprop_hue_mix_nothing c c = distance (hue c) (hue c) == 180 ==> isNaN (hue (Mix c c))
  226. 226. QuickCheckghci> quickCheck prop_hue_mix_nothingprop_hue_mix_nothing c c = distance (hue c) (hue c) == 180 ==> isNaN (hue (Mix c c))
  227. 227. QuickCheckghci> quickCheck prop_hue_mix_nothing*** Gave up! Passed only 23 tests.ghci>prop_hue_mix_nothing c c = distance (hue c) (hue c) == 180 ==> isNaN (hue (Mix c c))
  228. 228. QuickCheckprop_hue_mix_nothing c c = distance (hue c) (hue c) == 180 ==> isNaN (hue (Mix c c))
  229. 229. QuickCheckprop_hue_mix_nothing c c = distance (hue c) (hue c) == 180 ==> isNaN (hue (Mix c c))-- Can we easily find the complement of a color?
  230. 230. complement Red = ???complement Green = ???complement Blue = ???complement (Mix c c) = ???
  231. 231. complement Red = cyancomplement Green = ???complement Blue = ???complement (Mix c c) = ???
  232. 232. complement Red = cyancomplement Green = magentacomplement Blue = ???complement (Mix c c) = ???
  233. 233. complement Red = cyancomplement Green = magentacomplement Blue = yellowcomplement (Mix c c) = ???
  234. 234. complement Red = cyancomplement Green = magentacomplement Blue = yellowcomplement (Mix c c) = Mix ??? ???
  235. 235. complement Red = cyancomplement Green = magentacomplement Blue = yellowcomplement (Mix c c) = Mix (complement c ) (complement c )
  236. 236. QuickCheckprop_complement c = let h = hue c in not (isNaN h) ==> distance h (hue (complement c)) == 180
  237. 237. QuickCheckprop_complement c = let h = hue c in not (isNaN h) ==> distance h (hue (complement c)) == 180prop_hue_mix_complement c = isNaN (hue (Mix c (complement c)))
  238. 238. QuickCheckghci> quickCheck prop_complementprop_complement c = let h = hue c in not (isNaN h) ==> distance h (hue (complement c)) == 180prop_hue_mix_complement c = isNaN (hue (Mix c (complement c)))
  239. 239. ghci> quickCheck prop_complement+++ OK, passed 100 tests.ghci>
  240. 240. ghci> quickCheck prop_complement+++ OK, passed 100 tests.ghci> quickCheck prop_hue_mix_complement
  241. 241. ghci> quickCheck prop_complement+++ OK, passed 100 tests.ghci> quickCheck prop_hue_mix_complement+++ OK, passed 100 tests.ghci>
  242. 242. To be continued...
  243. 243. SummaryHaskell is functional.Haskell has types.QuickCheck is cool.
  244. 244. Preview: Infinite Listsprimes = sieve [2..] where sieve (p:xs) = p : sieve [x | x <- xs, rem x p /= 0]
  245. 245. Preview: IO (echo.hs)import System.Environment (getArgs)import Data.List (intercalate)main = do args <- getArgs putStrLn (intercalate " " args)
  246. 246. Preview: Parsers
  247. 247. Preview: Parse JSONdata Value = String String | Number Double | Object [(String, Value)] | Array [Value] | Bool Bool | Null
  248. 248. Preview: Parse JSONvalue = String <$>jsstring <|> Number <$>number <|> Object <$>commaGroup { pair } <|> Array <$>commaGroup [ value ] <|> Bool True <$ string "true" <|> Bool False <$ string "false" <|> Null <$ string "null"
  249. 249. Preview: Parse JSONpair :: Parser (String, Value)pair = do s <- jsstring sp_char_sp : v <- value spaces return (s, v)
  250. 250. To be continued...

×