Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Fun never stops. introduction to haskell programming language

915 views

Published on

Introduction to Haskell programming language that I did for London Scala User Group, Nov 2015

Published in: Technology
  • Be the first to comment

Fun never stops. introduction to haskell programming language

  1. 1. “Funneverstops. IntroductiontoHaskell Programminglanguage” twitter: @rabbitonweb, github: github.com/rabbitonweb
  2. 2. “Funneverstops. IntroductiontoHaskell Programminglanguage” twitter: @rabbitonweb, github: github.com/rabbitonweb FOR SCALA DEVELOPERS
  3. 3. WhylearnHaskell ???
  4. 4. TherearetwotypesofScaladevelopers:
  5. 5. TherearetwotypesofScaladevelopers: 1)thosewhoarehappytheynolongerprograminJava
  6. 6. TherearetwotypesofScaladevelopers: 1)thosewhoarehappytheynolongerprograminJava 2)ThoseWhoarepissedofftheyarenotyetusinghaskell
  7. 7. TherearetwotypesofScaladevelopers: 1)thosewhoarehappytheynolongerprograminJava 2)ThoseWhoarepissedofftheyarenotyetusinghaskell Let’s get a bit of that Haskell taste...
  8. 8. WhylearnHaskell?
  9. 9. WhylearnHaskell? HaskellisPureFunctional ProgrammingLanguage
  10. 10. WhatisFunctionalProgramming?
  11. 11. ❏ no assignment statements WhatisFunctionalProgramming?
  12. 12. ❏ no assignment statements ❏ no variables WhatisFunctionalProgramming?
  13. 13. ❏ no assignment statements ❏ no variables ❏ once given a value, never change WhatisFunctionalProgramming?
  14. 14. ❏ no assignment statements ❏ no variables ❏ once given a value, never change ❏ no side-effects at all WhatisFunctionalProgramming?
  15. 15. ❏ no assignment statements ❏ no variables ❏ once given a value, never change ❏ no side-effects at all WhatisFunctionalProgramming?
  16. 16. ❏ no assignment statements ❏ no variables ❏ once given a value, never change ❏ no side-effects at all WhatisFunctionalProgramming?
  17. 17. ❏ no assignment statements ❏ no variables ❏ once given a value, never change ❏ no side-effects at all WhatisFunctionalProgramming?
  18. 18. ❏ no assignment statements ❏ no variables ❏ once given a value, never change ❏ no side-effects at all WhatisFunctionalProgramming?
  19. 19. WhatisFunctionalProgramming? ❏ no assignment statements ❏ no variables ❏ once given a value, never change ❏ no side-effects at all “The functional programmer sounds rather like a mediæval monk, denying himself the pleasures of life in the hope that it will make him virtuous.”
  20. 20. WhyFunctionalProgrammingMatters?
  21. 21. WhyFunctionalProgrammingMatters? What procedural programming, dependency injection, actor model, microservices and clean architecture have in common?
  22. 22. WhyFunctionalProgrammingMatters? What procedural programming, dependency injection, actor model, microservices and clean architecture have in common?
  23. 23. WhyFunctionalProgrammingMatters? ❏ We strive for modularity What procedural programming, dependency injection, actor model, microservices and clean architecture have in common?
  24. 24. f(input): output
  25. 25. input f(input): output
  26. 26. input f(input): output output
  27. 27. input f(input): output output g(input): output
  28. 28. input f(input): output output g(input): output output
  29. 29. h = g o f input f(input): output output g(input): output output
  30. 30. WhyFunctionalProgrammingMatters? ❏ We strive for modularity
  31. 31. WhyFunctionalProgrammingMatters? ❏ We strive for modularity ❏ There is no concept of time
  32. 32. Whatwillthisfunctiondo? /** * This function returns a reversed list * @param list A list to be reversed * @return A reversed list */ def reverse[T](list: List[T]): List[T] = ???
  33. 33. Whatwillthisfunctiondo? /** * This function returns a reversed list * @param list A list to be reversed * @return A reversed list */ def reverse[T](list: List[T]): List[T] = ???
  34. 34. Whatwillthisfunctiondo? /** * This function returns a reversed list * @param list A list to be reversed * @return A reversed list def reverse[T](list: List[T]): List[T] = ???
  35. 35. Whatwillthisfunctiondo? /** * This function returns a reversed list * @param list A list to be reversed def reverse[T](list: List[T]): List[T] = ???
  36. 36. Whatwillthisfunctiondo? /** * This function returns a reversed list def reverse[T](list: List[T]): List[T] = ???
  37. 37. Whatwillthisfunctiondo? /** def reverse[T](list: List[T]): List[T] = ???
  38. 38. Whatwillthisfunctiondo? def reverse[T](list: List[T]): List[T] = ???
  39. 39. Whatwillthisfunctiondo? def reverse[T](list: List[T]): List[T] = list.sort
  40. 40. Whatwillthisfunctiondo?
  41. 41. Whatwillthisfunctiondo? def rhrggahaham[A](a: A): A = ???
  42. 42. Whatwillthisfunctiondo? def rhrggahaham[A](a: A): A = ??? Ifwrittenbyfunctionalprogrammer
  43. 43. Whatwillthisfunctiondo? def rhrggahaham[A](a: A): A = ???
  44. 44. Whatwillthisfunctiondo? def rhrggahaham[A](a: A): A = a
  45. 45. Whatwillthisfunctiondo? def identity[A](a: A): A = a
  46. 46. Whatwillthisfunctiondo? def rhrggahaham[A](a: A): A = a
  47. 47. Whatwillthisfunctiondo? def rhrggahaham[A](a: A): A = a
  48. 48. Whatwillthisfunctiondo? def rhrggahaham[A](a: A): A = a
  49. 49. Whatwillthisfunctiondo? def rhrggahaham(a: Int): Int = ???
  50. 50. Whatwillthisfunctiondo? def rhrggahaham(a: Int): Int = ??? Ifwrittenbyfunctionalprogrammer
  51. 51. Whatwillthisfunctiondo? def rhrggahaham(a: Int): Int = a a + 10 20
  52. 52. WhyFunctionalProgrammingMatters? ❏ We strive for modularity ❏ There is no concept of time
  53. 53. WhyFunctionalProgrammingMatters? ❏ We strive for modularity ❏ There is no concept of time ❏ We can reason about our code with ease
  54. 54. def curry
  55. 55. scala> def add(a: Int, b: Int) = a + b add: (a: Int, b: Int)Int
  56. 56. scala> def add(a: Int, b: Int) = a + b add: (a: Int, b: Int)Int scala> val curriedAdd = curry(add) curriedAdd: Int => (Int => Int) = <function1>
  57. 57. scala> def add(a: Int, b: Int) = a + b add: (a: Int, b: Int)Int scala> val curriedAdd = curry(add) curriedAdd: Int => (Int => Int) = <function1> scala> val add5 = curriedAdd(5) scala> add5(7) res1: Int = 12
  58. 58. def curry
  59. 59. def curry[A,B,C](f: (A, B) => C):
  60. 60. def curry[A,B,C](f: (A, B) => C): (A => (B => C)) =
  61. 61. def curry[A,B,C](f: (A, B) => C): (A => (B => C)) = (a: A) => ?
  62. 62. def curry[A,B,C](f: (A, B) => C): (A => (B => C)) = (a: A) => ( ? => ? )
  63. 63. def curry[A,B,C](f: (A, B) => C): (A => (B => C)) = (a: A) => ( (b: B) => ? )
  64. 64. def curry[A,B,C](f: (A, B) => C): (A => (B => C)) = (a: A) => ( (b: B) => f(a,b) )
  65. 65. WhyFunctionalProgrammingMatters? ❏ We strive for modularity ❏ There is no concept of time ❏ We can reason about our code with ease
  66. 66. WhyFunctionalProgrammingMatters? ❏ We strive for modularity ❏ There is no concept of time ❏ We can reason about our code with ease ❏ Just follow types
  67. 67. WhyFunctionalProgrammingMatters? ❏ We strive for modularity ❏ There is no concept of time ❏ We can reason about our code with ease ❏ Just follow types ❏ Lazy evaluation
  68. 68. WhyFunctionalProgrammingMatters? ❏ We strive for modularity ❏ There is no concept of time ❏ We can reason about our code with ease ❏ Just follow types ❏ Lazy evaluation
  69. 69. WhylearnHaskell ???
  70. 70. WhylearnHaskell? HaskellisPureFunctional ProgrammingLanguage
  71. 71. WhylearnHaskell? HaskellisPureFunctional ProgrammingLanguage
  72. 72. WhylearnHaskell? HaskellisPureFunctional ProgrammingLanguage
  73. 73. https://xkcd.com/1312/
  74. 74. World-> (World,A)
  75. 75. World-> (World,A) "aninteractiveprogramisapurefunctionthattakesthe current'stateoftheworld'asitsarg.andproducesa modifiedworldasresult"
  76. 76. World-> (World,A) “Protip:Don'ttrytotrackreal-worldstateinyourcode. Insteadtakeitasanargument,sinceonlytheworld knowswhatstateit'sin.”
  77. 77. World->(World,A)
  78. 78. World->(World,A) PURE
  79. 79. World->(World,A)
  80. 80. World->(World,A)
  81. 81. World->(World,A)
  82. 82. World->(World,A)
  83. 83. World->(World,A)
  84. 84. World->(World,A)
  85. 85. World->(World,A)
  86. 86. World->(World,A)
  87. 87. World->(World,A)
  88. 88. World->(World,A)
  89. 89. World->(World,A)
  90. 90. World->(World,A)
  91. 91. World->(World,A)
  92. 92. World->(World,A)
  93. 93. World->(World,A) IMPURE
  94. 94. World->(World,A)
  95. 95. World->(World,A) f
  96. 96. World->(World,A) currentStateOfTheWorld = stateOfTheWorld f
  97. 97. World->(World,A) currentStateOfTheWorld = stateOfTheWorld = f currentStateOfTheWorld f
  98. 98. World->(World,A) currentStateOfTheWorld = stateOfTheWorld = f currentStateOfTheWorld f
  99. 99. World->(World,A) currentStateOfTheWorld = stateOfTheWorld = f currentStateOfTheWorld f
  100. 100. World->(World,A) currentStateOfTheWorld = stateOfTheWorld = f currentStateOfTheWorld f
  101. 101. World->(World,A) currentStateOfTheWorld = stateOfTheWorld = f currentStateOfTheWorld f
  102. 102. World->(World,A) currentStateOfTheWorld = stateOfTheWorld (newWorld, someValue) = f currentStateOfTheWorld f
  103. 103. World->(World,A) currentStateOfTheWorld = stateOfTheWorld (newWorld, someValue) = f currentStateOfTheWorld modifyWorldWith newWorld f
  104. 104. World->(World,A) currentStateOfTheWorld = stateOfTheWorld (newWorld, someValue) = f currentStateOfTheWorld modifyWorldWith newWorld display someValue f
  105. 105. JustaLittlebitof history
  106. 106. HaskellHistoryinanutshell
  107. 107. HaskellHistoryinanutshell ❏ Miranda released 1985 - de facto FP ‘standard’
  108. 108. HaskellHistoryinanutshell ❏ Miranda released 1985 - de facto FP ‘standard’ ❏ At the FPCA'87 few formed a consensus that an open standard should be defined for FP languages
  109. 109. HaskellHistoryinanutshell ❏ Miranda released 1985 - de facto FP ‘standard’ ❏ At the FPCA'87 few formed a consensus that an open standard should be defined for FP languages ❏ Haskell 1.0 defined in 1990
  110. 110. HaskellHistoryinanutshell ❏ Miranda released 1985 - de facto FP ‘standard’ ❏ At the FPCA'87 few formed a consensus that an open standard should be defined for FP languages ❏ Haskell 1.0 defined in 1990 ❏ Haskell 98 in late 1997
  111. 111. HaskellHistoryinanutshell ❏ Miranda released 1985 - de facto FP ‘standard’ ❏ At the FPCA'87 few formed a consensus that an open standard should be defined for FP languages ❏ Haskell 1.0 defined in 1990 ❏ Haskell 98 in late 1997 “(...) intended to specify a stable, minimal, portable version of the language and an accompanying standard library for teaching, and as a base for future extensions.”
  112. 112. HaskellHistoryinanutshell ❏ Miranda released 1985 - de facto FP ‘standard’ ❏ At the FPCA'87 few formed a consensus that an open standard should be defined for FP languages ❏ Haskell 1.0 defined in 1990 ❏ Haskell 98 in late 1997
  113. 113. HaskellHistoryinanutshell ❏ Miranda released 1985 - de facto FP ‘standard’ ❏ At the FPCA'87 few formed a consensus that an open standard should be defined for FP languages ❏ Haskell 1.0 defined in 1990 ❏ Haskell 98 in late 1997 ❏ “The Haskell 98 Report” in 1999
  114. 114. HaskellHistoryinanutshell ❏ Miranda released 1985 - de facto FP ‘standard’ ❏ At the FPCA'87 few formed a consensus that an open standard should be defined for FP languages ❏ Haskell 1.0 defined in 1990 ❏ Haskell 98 in late 1997 ❏ “The Haskell 98 Report” in 1999 ❏ “The Haskell 2010 Report” in 2009/2010
  115. 115. HaskellHistoryinanutshell ❏ Miranda released 1985 - de facto FP ‘standard’ ❏ At the FPCA'87 few formed a consensus that an open standard should be defined for FP languages ❏ Haskell 1.0 defined in 1990 ❏ Haskell 98 in late 1997 ❏ “The Haskell 98 Report” in 1999 ❏ “The Haskell 2010 Report” in 2009/2010 ❏ Further Haskell evolves rapidly around GHC
  116. 116. Showussomecode already!
  117. 117. GHC-GlassgowHaskellCompiler
  118. 118. GHC-GlassgowGloriousHaskellCompiler
  119. 119. GHC-GlassgowGloriousHaskellCompiler ❏ > ghci ❏ :t ❏ +set :t ❏ :load ❏ Emacs + Haskell mode ❏ C-c C-b ❏ C-c C-l
  120. 120. FunWithFunctions
  121. 121. FunWithFunctions helloWorld = “Hello World”
  122. 122. FunWithFunctions ❏ function without parameters is called definition helloWorld = “Hello World”
  123. 123. FunWithFunctions ❏ function without parameters is called definition ❏ function name must start with small letter helloWorld = “Hello World”
  124. 124. FunWithFunctions ❏ function without parameters is called definition ❏ function name must start with small letter > helloWorld "Hello World" it :: [Char] helloWorld = “Hello World”
  125. 125. FunWithFunctions
  126. 126. FunWithFunctions london u = “London “ ++ u
  127. 127. FunWithFunctions > :t london london :: [Char] -> [Char] london u = “London “ ++ u
  128. 128. FunWithFunctions > :t london london :: [Char] -> [Char] > london "baby" "london baby" it :: [Char] london u = “London “ ++ u
  129. 129. FunWithFunctions > :t london london :: [Char] -> [Char] > london "baby" "london baby" it :: [Char] london :: [Char] -> [Char] london u = “London “ ++ u
  130. 130. FunWithFunctions isA c = c == 'A'
  131. 131. FunWithFunctions isA :: Char -> Bool isA c = c == 'A'
  132. 132. FunWithFunctions > isA 'd' False > isA 'A' True isA :: Char -> Bool isA c = c == 'A'
  133. 133. FunWithFunctions
  134. 134. FunWithFunctions prefixMe c str = [c] ++ " " ++ str
  135. 135. FunWithFunctions > prefixMe '_' "word" "_ word" it :: [Char] prefixMe c str = [c] ++ " " ++ str
  136. 136. FunWithFunctions > :t prefixMe prefixMe :: Char -> [Char] -> [Char] > prefixMe '_' "word" "_ word" it :: [Char] prefixMe c str = [c] ++ " " ++ str
  137. 137. FunWithFunctions > :t prefixMe prefixMe :: Char -> ([Char] -> [Char]) > prefixMe '_' "word" "_ word" it :: [Char] prefixMe c str = [c] ++ " " ++ str
  138. 138. FunWithFunctions
  139. 139. FunWithFunctions answerToEverything = 42
  140. 140. FunWithFunctions answerToEverything = 42 complexCalc x y z = x * y * z * answerToEverything
  141. 141. FunWithFunctions > :t complexCalc complexCalc :: Integer -> Integer -> Integer -> Integer answerToEverything = 42 complexCalc x y z = x * y * z * answerToEverything
  142. 142. FunWithFunctions > :t complexCalc complexCalc :: Integer -> Integer -> Integer -> Integer complexCalc :: Integer -> (Integer -> (Integer -> Integer)) answerToEverything = 42 complexCalc x y z = x * y * z * answerToEverything
  143. 143. FunWithFunctions > :t complexCalc complexCalc :: Integer -> Integer -> Integer -> Integer complexCalc :: Integer -> (Integer -> (Integer -> Integer)) > complexCalc 10 20 30 answerToEverything = 42 complexCalc x y z = x * y * z * answerToEverything
  144. 144. FunWithFunctions > :t complexCalc complexCalc :: Integer -> Integer -> Integer -> Integer complexCalc :: Integer -> (Integer -> (Integer -> Integer)) > complexCalc 10 20 30 > ((complexCalc 10) 20) 30 answerToEverything = 42 complexCalc x y z = x * y * z * answerToEverything
  145. 145. FunWithTypes
  146. 146. FunWithTypes ❏ We’ve already seen: Char, Integers & Bool
  147. 147. FunWithTypes ❏ We’ve already seen: Char, Integers & Bool ❏ Other build-in types:
  148. 148. FunWithTypes ❏ We’ve already seen: Char, Integers & Bool ❏ Other build-in types: ❏ Int, Float, Doubles
  149. 149. FunWithTypes ❏ We’ve already seen: Char, Integers & Bool ❏ Other build-in types: ❏ Int, Float, Doubles ❏ Tuples
  150. 150. FunWithTypes ❏ We’ve already seen: Char, Integers & Bool ❏ Other build-in types: ❏ Int, Float, Doubles ❏ Tuples > (False, "Is it?") it :: (Bool, [Char]) > (10.4, True, "Values", 'Y') it :: (Double, Bool, [Char], Char)
  151. 151. FunWithTypes ❏ We’ve already seen: Char, Integers & Bool ❏ Other build-in types: ❏ Int, Float, Doubles ❏ Tuples
  152. 152. FunWithTypes ❏ We’ve already seen: Char, Integers & Bool ❏ Other build-in types: ❏ Int, Float, Doubles ❏ Tuples ❏ Lists > [False, False, True] it :: [Bool] > [10, 20, 30] it :: [Integer] > ["one", "two", "three"] it :: [[Char]]
  153. 153. Polymorphic types
  154. 154. Polymorphic types > length [False, False, True] 3
  155. 155. Polymorphic types > length [False, False, True] 3 > length [10, 20, 30, 40] 4
  156. 156. Polymorphic types > length [False, False, True] 3 > length [10, 20, 30, 40] 4 > length ["one", "two", "three"] 3
  157. 157. Polymorphic types > length [False, False, True] 3 > length [10, 20, 30, 40] 4 > length ["one", "two", "three"] 3 length :: [a] -> Int
  158. 158. Polymorphic types > length [False, False, True] 3 > length [10, 20, 30, 40] 4 > length ["one", "two", "three"] 3 length :: [a] -> Int ‘a’ is a type variable, which means that length can be applied to list of any type
  159. 159. List101
  160. 160. List101 numbers = [1, 3, 5, 7]
  161. 161. List101 numbers = [1, 3, 5, 7] numbers !! 2 -> 5
  162. 162. List101 numbers = [1, 3, 5, 7] numbers !! 2 -> 5 null numbers -> False
  163. 163. List101 numbers = [1, 3, 5, 7] numbers !! 2 -> 5 null numbers -> False head numbers -> 1
  164. 164. List101 numbers = [1, 3, 5, 7] numbers !! 2 -> 5 null numbers -> False head numbers -> 1 tail numbers -> [3, 5, 7]
  165. 165. List101 numbers = [1, 3, 5, 7] numbers !! 2 -> 5 null numbers -> False head numbers -> 1 tail numbers -> [3, 5, 7] init numbers -> [1, 3, 5]
  166. 166. List101 numbers = [1, 3, 5, 7] numbers !! 2 -> 5 null numbers -> False head numbers -> 1 tail numbers -> [3, 5, 7] init numbers -> [1, 3, 5] last numbers -> 7
  167. 167. List101 numbers = [1, 3, 5, 7] numbers !! 2 -> 5 null numbers -> False head numbers -> 1 tail numbers -> [3, 5, 7] init numbers -> [1, 3, 5] last numbers -> 7 drop 2 numbers -> [5, 7]
  168. 168. List101 numbers = [1, 3, 5, 7] numbers !! 2 -> 5 null numbers -> False head numbers -> 1 tail numbers -> [3, 5, 7] init numbers -> [1, 3, 5] last numbers -> 7 drop 2 numbers -> [5, 7] take 2 numbers -> [1, 3]
  169. 169. List101 numbers = [1, 3, 5, 7] numbers !! 2 -> 5 null numbers -> False head numbers -> 1 tail numbers -> [3, 5, 7] init numbers -> [1, 3, 5] last numbers -> 7 drop 2 numbers -> [5, 7] take 2 numbers -> [1, 3] elem 5 numbers -> True
  170. 170. List101
  171. 171. List101 [1..6] -> [1, 2, 3, 4, 5, 6]
  172. 172. List101 [1..6] -> [1, 2, 3, 4, 5, 6] [1,3,.., 20] -> [1,3,5,7,9,11,13,15,17,19]
  173. 173. List101 [1..6] -> [1, 2, 3, 4, 5, 6] [1,3,.., 20] -> [1,3,5,7,9,11,13,15,17,19] [1..] -> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, ...
  174. 174. List101 [1..6] -> [1, 2, 3, 4, 5, 6] [1,3,.., 20] -> [1,3,5,7,9,11,13,15,17,19] take 5 [1..] -> [1, 2, 3, 4, 5]
  175. 175. List101 [1..6] -> [1, 2, 3, 4, 5, 6] [1,3,.., 20] -> [1,3,5,7,9,11,13,15,17,19] take 5 [1..] -> [1, 2, 3, 4, 5] (cycle [0, 1]) -> [0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,..
  176. 176. List101 [1..6] -> [1, 2, 3, 4, 5, 6] [1,3,.., 20] -> [1,3,5,7,9,11,13,15,17,19] take 5 [1..] -> [1, 2, 3, 4, 5] take 6 (cycle [0, 1]) -> [0,1,0,1,0,1]
  177. 177. List101 [1..6] -> [1, 2, 3, 4, 5, 6] [1,3,.., 20] -> [1,3,5,7,9,11,13,15,17,19] take 5 [1..] -> [1, 2, 3, 4, 5] take 6 (cycle [0, 1]) -> [0,1,0,1,0,1] take 3 (repeat 2) -> [2, 2, 2]
  178. 178. List101
  179. 179. List101 [2 ^ x | x <- [1..5]] -> [2,4,8,16,32]
  180. 180. List101 [2 ^ x | x <- [1..5]] -> [2,4,8,16,32] take 7 [2 ^ x | x <- [1..]] -> [2,4,8,16,32,64,128]
  181. 181. List101 [2 ^ x | x <- [1..5]] -> [2,4,8,16,32] take 7 [2 ^ x | x <- [1..]] -> [2,4,8,16,32,64,128] [(x,y) | x <- [1..5], y <- [1..5]] -> [(1,1),(1,2),(1,3), ...
  182. 182. List101 [2 ^ x | x <- [1..5]] -> [2,4,8,16,32] take 7 [2 ^ x | x <- [1..]] -> [2,4,8,16,32,64,128] [(x,y) | x <- [1..5], y <- [1..5]] -> [(1,1),(1,2),(1,3), … [(x,y) | x <- [1..2], y <- [x..2]] -> [(1,1),(1,2),(2,2)]
  183. 183. List101 [2 ^ x | x <- [1..5]] -> [2,4,8,16,32] take 7 [2 ^ x | x <- [1..]] -> [2,4,8,16,32,64,128] [(x,y) | x <- [1..5], y <- [1..5]] -> [(1,1),(1,2),(1,3), ... [(x,y) | x <- [1..2], y <- [x..2]] -> [(1,1),(1,2),(2,2)] [x | x <- [1..7], x `mod` 2 == 0] -> [2, 4, 6]
  184. 184. List101 [2 ^ x | x <- [1..5]] -> [2,4,8,16,32] take 7 [2 ^ x | x <- [1..]] -> [2,4,8,16,32,64,128] [(x,y) | x <- [1..5], y <- [1..5]] -> [(1,1),(1,2),(1,3), ... [(x,y) | x <- [1..2], y <- [x..2]] -> [(1,1),(1,2),(2,2)] [x | x <- [1..7], x `mod` 2 == 0] -> [2, 4, 6] zip "abc" [1,2,3] -> [('a',1),('b',2),('c',3)]
  185. 185. List101 [2 ^ x | x <- [1..5]] -> [2,4,8,16,32] take 7 [2 ^ x | x <- [1..]] -> [2,4,8,16,32,64,128] [(x,y) | x <- [1..5], y <- [1..5]] -> [(1,1),(1,2),(1,3), ... [(x,y) | x <- [1..2], y <- [x..2]] -> [(1,1),(1,2),(2,2)] [x | x <- [1..7], x `mod` 2 == 0] -> [2, 4, 6] zip "abc" [1,2,3] -> [('a',1),('b',2),('c',3)] zip "abc" (cycle [0,1]) -> [('a',0),('b',1),('c',0)]
  186. 186. List101 [2 ^ x | x <- [1..5]] -> [2,4,8,16,32] take 7 [2 ^ x | x <- [1..]] -> [2,4,8,16,32,64,128] [(x,y) | x <- [1..5], y <- [1..5]] -> [(1,1),(1,2),(1,3), ... [(x,y) | x <- [1..2], y <- [x..2]] -> [(1,1),(1,2),(2,2)] [x | x <- [1..7], x `mod` 2 == 0] -> [2, 4, 6] zip "abc" [1,2,3] -> [('a',1),('b',2),('c',3)] zip "abc" (cycle [0,1]) -> [('a',0),('b',1),('c',0)] zipWith (+) [1,2,3] [4,5,6] -> [5,7,9]
  187. 187. Classes
  188. 188. Classes caseclassFoo(...)???
  189. 189. Classes caseclassFoo(...)??? No,notthoseclasses.Typeclasses.
  190. 190. TypeClasses Type class is a set of types which support certain collection of functions defined by the class.
  191. 191. TypeClasses ❏ Eq
  192. 192. TypeClasses ❏ Eq (==) :: a -> a -> Bool; (/=) :: a -> a -> Bool
  193. 193. TypeClasses ❏ Eq (==) :: a -> a -> Bool; (/=) :: a -> a -> Bool ❏ Ord
  194. 194. TypeClasses ❏ Eq (==) :: a -> a -> Bool; (/=) :: a -> a -> Bool ❏ Ord < , <= , > , >= :: a -> a -> Bool; min , max :: a -> a -> a
  195. 195. TypeClasses ❏ Eq (==) :: a -> a -> Bool; (/=) :: a -> a -> Bool ❏ Ord < , <= , > , >= :: a -> a -> Bool; min , max :: a -> a -> a ❏ Show
  196. 196. TypeClasses ❏ Eq (==) :: a -> a -> Bool; (/=) :: a -> a -> Bool ❏ Ord < , <= , > , >= :: a -> a -> Bool; min , max :: a -> a -> a ❏ Show show :: a -> String
  197. 197. TypeClasses ❏ Eq (==) :: a -> a -> Bool; (/=) :: a -> a -> Bool ❏ Ord < , <= , > , >= :: a -> a -> Bool; min , max :: a -> a -> a ❏ Show show :: a -> String ❏ Read
  198. 198. TypeClasses ❏ Eq (==) :: a -> a -> Bool; (/=) :: a -> a -> Bool ❏ Ord < , <= , > , >= :: a -> a -> Bool; min , max :: a -> a -> a ❏ Show show :: a -> String ❏ Read read :: String -> a
  199. 199. TypeClasses > 10 == 20 False
  200. 200. TypeClasses > 10 == 20 False > 10 < 20 True
  201. 201. TypeClasses > 10 == 20 False > 10 < 20 True > show 1 ++ " is a number" "1 is a number"
  202. 202. TypeClasses > 10 == 20 False > 10 < 20 True > show 1 ++ " is a number" "1 is a number" > read "5" + 10 15
  203. 203. TypeClasses > 10 == 20 False > 10 < 20 True > show 1 ++ " is a number" "1 is a number" > read "5" + 10 15 > read "5" <interactive>:85:1: No instance for (Read a0) arising from a use of `read' *Main> read "5" :: Integer 5 it :: Integer
  204. 204. TypeClasses > 10 == 20 False > 10 < 20 True > show 1 ++ " is a number" "1 is a number" > read "5" + 10 15 > read "5" :: Integer 5
  205. 205. Typeclasses&classconstraints add a b = a + b
  206. 206. Typeclasses&classconstraints add :: Num a => a -> a -> a add a b = a + b
  207. 207. Typeclasses&classconstraints add :: Num a => a -> a -> a add a b = a + b add 10 20
  208. 208. Typeclasses&classconstraints add :: Num a => a -> a -> a add a b = a + b add 10 20 add 5.0 7.0
  209. 209. Typeclasses&classconstraints add :: Num a => a -> a -> a add a b = a + b add 10 20 add 5.0 7.0 weirdo n d str = (n + 2, d / 2.0, str ++ "!!")
  210. 210. Typeclasses&classconstraints add :: Num a => a -> a -> a add a b = a + b add 10 20 add 5.0 7.0 weirdo :: (Fractional t1, Num t) => t -> t1 -> [Char] -> (t, t1, [Char]) weirdo n d str = (n + 2, d / 2.0, str ++ "!!")
  211. 211. Typeclasses&classconstraints add :: Num a => a -> a -> a add a b = a + b add 10 20 add 5.0 7.0 weirdo :: (Fractional t1, Num t) => t -> t1 -> [Char] -> (t, t1, [Char]) weirdo n d str = (n + 2, d / 2.0, str ++ "!!") weirdo 7 7.0 “kuku”
  212. 212. Typeclasses&classconstraints add :: Num a => a -> a -> a add a b = a + b add 10 20 add 5.0 7.0 weirdo :: (Fractional t1, Num t) => t -> t1 -> [Char] -> (t, t1, [Char]) weirdo n d str = (n + 2, d / 2.0, str ++ "!!") weirdo 7 7.0 “kuku” weirdo 7.0 5.0 “mono”
  213. 213. FunWithFunctions,Part2 sum :: Num a => [a] -> a
  214. 214. FunWithFunctions,Part2 sum :: Num a => [a] -> a sum list = if null list then 0 else 1 + sum (tail list)
  215. 215. FunWithFunctions,Part2 sum :: Num a => [a] -> a
  216. 216. FunWithFunctions,Part2 sum :: Num a => [a] -> a sum [] = 0
  217. 217. FunWithFunctions,Part2 sum :: Num a => [a] -> a sum [] = 0 sum x:xs = 1 + sum xs
  218. 218. FunWithFunctions,Part2 programmingLanguage :: [Char] -> [Char]
  219. 219. FunWithFunctions,Part2 programmingLanguage :: [Char] -> [Char] programmingLanguage "Scala" = "Good"
  220. 220. FunWithFunctions,Part2 programmingLanguage :: [Char] -> [Char] programmingLanguage "Scala" = "Good" programmingLanguage "Haskell" = "Even better!"
  221. 221. FunWithFunctions,Part2 programmingLanguage :: [Char] -> [Char] programmingLanguage "Scala" = "Good" programmingLanguage "Haskell" = "Even better!" programmingLanguage other = "Meh..." ++ other ++ ", pf.."
  222. 222. FunWithFunctions,Part2 first :: (a, b, c) -> a first (x, _, _) = x second :: (a, b, c) -> b second (_, y, _) = y third :: (a, b, c) -> c third (_, _, z) = z
  223. 223. FunWithFunctions,Part2 rankMe :: (Num a, Ord a) => a -> [Char]
  224. 224. FunWithFunctions,Part2 rankMe :: (Num a, Ord a) => a -> [Char] rankMe lines
  225. 225. FunWithFunctions,Part2 rankMe :: (Num a, Ord a) => a -> [Char] rankMe lines | lines > 100 = "Senior"
  226. 226. FunWithFunctions,Part2 rankMe :: (Num a, Ord a) => a -> [Char] rankMe lines | lines > 100 = "Senior" | lines > 30 = "Regular"
  227. 227. FunWithFunctions,Part2 rankMe :: (Num a, Ord a) => a -> [Char] rankMe lines | lines > 100 = "Senior" | lines > 30 = "Regular" | lines >= 0 = "Junior"
  228. 228. FunWithFunctions,Part2 rankMe :: (Num a, Ord a) => a -> [Char] rankMe lines | lines > 100 = "Senior" | lines > 30 = "Regular" | lines >= 0 = "Junior" | lines < 0 = "Congrats! You are a true Hacker!"
  229. 229. FunWithFunctions,Part2 rankMe :: (Num a, Ord a) => a -> a -> a -> [Char] rankMe added deleted modified | lines > 100 = "Senior" | lines > 30 = "Regular" | lines >= 0 = "Junior" | lines < 0 = "Congrats! You are a true Hacker!"
  230. 230. FunWithFunctions,Part2 rankMe :: (Num a, Ord a) => a -> a -> a -> [Char] rankMe added deleted modified | lines > 100 = "Senior" | lines > 30 = "Regular" | lines >= 0 = "Junior" | lines < 0 = "Congrats! You are a true Hacker!" where lines = added - deleted
  231. 231. Creatingnewtypes
  232. 232. Creatingnewtypes-aliasing
  233. 233. Creatingnewtypes-aliasing type String = [Char]
  234. 234. Creatingnewtypes-aliasing type String = [Char] type Point = (Int, Int)
  235. 235. Creatingnewtypes-aliasing type String = [Char] type Point = (Int, Int) type Parser a = String -> (a, String)
  236. 236. Creatingnewtypes
  237. 237. Creatingnewtypes-Datadeclarations
  238. 238. Creatingnewtypes-Datadeclarations data OS = Windows | OSX | Linux | Unix
  239. 239. Creatingnewtypes-Datadeclarations data OS = Windows | OSX | Linux | Unix bootup :: OS -> [Char]
  240. 240. Creatingnewtypes-Datadeclarations data OS = Windows | OSX | Linux | Unix bootup :: OS -> [Char] bootup Unix = "Up and running"
  241. 241. Creatingnewtypes-Datadeclarations data OS = Windows | OSX | Linux | Unix bootup :: OS -> [Char] bootup Unix = "Up and running" bootup Linux = "Well, I was actually never down..."
  242. 242. Creatingnewtypes-Datadeclarations data OS = Windows | OSX | Linux | Unix bootup :: OS -> [Char] bootup Unix = "Up and running" bootup Linux = "Well, I was actually never down..." bootup OSX = "Non-sufficient Starbucks coffee, please refill"
  243. 243. Creatingnewtypes-Datadeclarations data OS = Windows | OSX | Linux | Unix bootup :: OS -> [Char] bootup Unix = "Up and running" bootup Linux = "Well, I was actually never down..." bootup OSX = "Non-sufficient Starbucks coffee, please refill" bootup Windows = "Upgrading to Windows 10, this should take a second.."
  244. 244. Creatingnewtypes-Datadeclarations data OS = Windows | OSX | Linux | Unix
  245. 245. Creatingnewtypes-Datadeclarations data OS = Windows | OSX | Linux | Unix class Bootable a where boot :: a -> [Char]
  246. 246. Creatingnewtypes-Datadeclarations data OS = Windows | OSX | Linux | Unix class Bootable a where boot :: a -> [Char] instance Bootable OS where boot Unix = "Up and running" boot Linux = "Well, I was actually never down..." boot OSX = "Non-sufficient Starbucks coffee, please refill" boot Windows = "Upgrading to Windows 10, this should take a second.."
  247. 247. Creatingnewtypes-Datadeclarations data OS = Windows | OSX | Linux | Unix
  248. 248. Creatingnewtypes-Datadeclarations data OS = Windows | OSX | Linux | Unix instance Eq OS where Unix == Unix = True Linux == Linux = True OSX == OSX = True Windows == Windows = True _ == _ = False
  249. 249. Creatingnewtypes-Datadeclarations data OS = Windows | OSX | Linux | Unix instance Eq OS where Unix == Unix = True Linux == Linux = True OSX == OSX = True Windows == Windows = True _ == _ = False > Unix == Windows False
  250. 250. Creatingnewtypes-Datadeclarations data OS = Windows | OSX | Linux | Unix
  251. 251. Creatingnewtypes-Datadeclarations data OS = Windows | OSX | Linux | Unix instance Show OS where show Unix = "Unix" show Linux = "Linux" show OSX = "OSX" show Windows = "Windows"
  252. 252. Creatingnewtypes-Datadeclarations data OS = Windows | OSX | Linux | Unix instance Show OS where show Unix = "Unix" show Linux = "Linux" show OSX = "OSX" show Windows = "Windows" > show Unix "Unix"
  253. 253. Creatingnewtypes-Datadeclarations data OS = Windows | OSX | Linux | Unix
  254. 254. Creatingnewtypes-Datadeclarations data OS = Windows | OSX | Linux | Unix deriving (Eq, Ord, Show, Read)
  255. 255. Creatingnewtypes-Datadeclarations data OS = Windows | OSX | Linux | Unix deriving (Eq, Ord, Show, Read) > Windows == Unix False
  256. 256. Creatingnewtypes-Datadeclarations data OS = Windows | OSX | Linux | Unix deriving (Eq, Ord, Show, Read) > Windows == Unix False > show Windows "Windows" > read "Windows"::OS Windows > Linux > Windows True
  257. 257. Creatingnewtypes-Datadeclarations data Shape = Circle Float | Rect Float Float deriving Show > Circle 10 Circle 10.0 data Option a = Nothing | Some a deriving Show > Some “one” Some “one”
  258. 258. Creatingnewtypes-Datadeclarations data Shape = Circle Float | Rect Float Float deriving Show > Circle 10 Circle 10.0 data Option a = Nothing | Some a deriving Show > Some “one” Some “one”
  259. 259. Expressiveness
  260. 260. Quicksort
  261. 261. Quicksort qs [] = []
  262. 262. Quicksort qs [] = [] qs (x : xs) = qs smaller ++ [x] ++ qs larger
  263. 263. Quicksort qs [] = [] qs (x : xs) = qs smaller ++ [x] ++ qs larger where smaller = [a | a <- xs, a <= x] larger = [b | b <- xs, b > x]
  264. 264. Quicksort qs [] = [] qs (x : xs) = qs smaller ++ [x] ++ qs larger where smaller = [a | a <- xs, a <= x] larger = [b | b <- xs, b > x] > qs [3,7,1,9,3,10] [1,3,3,7,9,10]
  265. 265. FizzBuzz
  266. 266. FizzBuzz 1,
  267. 267. FizzBuzz 1,2
  268. 268. FizzBuzz 1,2,Fizz,
  269. 269. FizzBuzz 1,2,Fizz,4,Buzz,
  270. 270. FizzBuzz 1,2,Fizz,4,Buzz,Fizz,7,8,Fizz,Buzz,11,12,13,
  271. 271. FizzBuzz 1,2,Fizz,4,Buzz,Fizz,7,8,Fizz,Buzz,11,12,13,14,FizzBuzz,..
  272. 272. FizzBuzz
  273. 273. FizzBuzz fizzes = cycle ["", "", "fizz"] buzzes = cycle ["", "", "", "", "buzz"]
  274. 274. FizzBuzz fizzes = cycle ["", "", "fizz"] buzzes = cycle ["", "", "", "", "buzz"] pattern = zipWith (++) fizzes buzzes
  275. 275. FizzBuzz fizzes = cycle ["", "", "fizz"] buzzes = cycle ["", "", "", "", "buzz"] pattern = zipWith (++) fizzes buzzes > take 16 pattern ["","","fizz","","buzz","fizz","","","fizz","buzz",""," fizz","","","fizzbuzz",""]
  276. 276. FizzBuzz fizzes = cycle ["", "", "fizz"] buzzes = cycle ["", "", "", "", "buzz"] pattern = zipWith (++) fizzes buzzes
  277. 277. FizzBuzz fizzes = cycle ["", "", "fizz"] buzzes = cycle ["", "", "", "", "buzz"] pattern = zipWith (++) fizzes buzzes fizzbuzz = zipWith combine pattern [1..] where combine word number = if null word then show number else word
  278. 278. FizzBuzz fizzes = cycle ["", "", "fizz"] buzzes = cycle ["", "", "", "", "buzz"] pattern = zipWith (++) fizzes buzzes fizzbuzz = zipWith combine pattern [1..] where combine word number = > take 16 pattern if null word then show number else word ["1","2","fizz","4","buzz","fizz","7","8","fizz","buzz"," 11","fizz","13","14","fizzbuzz","16"]
  279. 279. Whatnext?
  280. 280. Whatnext?
  281. 281. Whatnext? 1. Read “Why Functional Programming Matters paper”
  282. 282. Whatnext? 1. Read “Why Functional Programming Matters paper” 2. Try to implement examples from that paper using Haskell
  283. 283. Whatnext? 1. Read “Why Functional Programming Matters paper” 2. Try to implement examples from that paper using Haskell 3. Sign for FP101x
  284. 284. Whatnext? 1. Read “Why Functional Programming Matters paper” 2. Try to implement examples from that paper using Haskell 3. Sign for FP101x https://courses.edx.org/courses/course-v1: DelftX+FP101x+3T2015/courseware/79633017711e44c9878df4f33701 4766/
  285. 285. Whatnext? 1. Read “Why Functional Programming Matters paper” 2. Try to implement examples from that paper using Haskell 3. Sign for FP101x 4. Try out Frege (Haskell on the JVM)
  286. 286. Whatnext? 1. Read “Why Functional Programming Matters paper” 2. Try to implement examples from that paper using Haskell 3. Sign for FP101x 4. Try out Frege (Haskell on the JVM) https://github.com/Frege/frege
  287. 287. PawelSzulc
  288. 288. PawelSzulc twitter: @rabbitonweb,
  289. 289. PawelSzulc twitter: @rabbitonweb, github: github.com/rabbitonweb
  290. 290. PawelSzulc twitter: @rabbitonweb, github: github.com/rabbitonweb blog: rabbitonweb.com
  291. 291. PawelSzulc THANKYOUVERYMUCH twitter: @rabbitonweb, github: github.com/rabbitonweb blog: rabbitonweb.com

×