O slideshow foi denunciado.
Utilizamos seu perfil e dados de atividades no LinkedIn para personalizar e exibir anúncios mais relevantes. Altere suas preferências de anúncios quando desejar.

Hiking through the Functional Forest with Fizz Buzz

794 visualizações

Publicada em

FizzBuzz the interview question which we all laugh at. What if I told you that FizzBuzz can be used as a tool to navigate your way through the functional forest? Join me on a short hike through the functional forest using FizzBuzz to navigate our way. We’ll look at Union Types, Pattern Matching, and Higher Order Functions all while staying in the domain of FizzBuzz. You’ll never look at FizzBuzz the same way again.

  • Seja o primeiro a comentar

Hiking through the Functional Forest with Fizz Buzz

  1. 1. Hiking through the Functional Forest with FizzBuzz Mike Harris | @MikeMKH | comp-phil.blogspot.com
  2. 2. The Functional Forest and Object Oriented City
  3. 3. The Functional Forest and Object Oriented City
  4. 4. let itinerary n = match n with | 0 -> "Rules" | 1 -> "Pattern Matching" | 2 -> "Types" | 3 -> "Higher Order Functions" | _ -> "Farewell" // val itinerary : n:int -> string 
 

  5. 5. let itinerary n = match n with | 0 -> "Rules" | 1 -> "Pattern Matching" | 2 -> "Types" | 3 -> "Higher Order Functions" | _ -> "Farewell" itinerary 0 // val it : string = 
 “Rules"
  6. 6. FizzBuzz number FizzBuzzer text
  7. 7. int int -> string string
  8. 8. Rules • x | 3 and x | 5 => FizzBuzz • x | 3 => Fizz • x | 5 => Buzz • x => string x
  9. 9. Rules • x | 3 and x | 5 => FizzBuzz • x | 3 => Fizz • x | 5 => Buzz • x => string x Specific General
  10. 10. 2 FizzBuzzer 2 x
  11. 11. 33 FizzBuzzer Fizz x | 3
  12. 12. 55 FizzBuzzer Buzz x | 5
  13. 13. 45 FizzBuzzer FizzBuzz x | 3
  14. 14. Conditional
  15. 15. x Fizz
 Buzz Fizz Buzz x | 15 x | 3 x | 5 xelse Specific General
  16. 16. 2 x | 15 x | 3 x | 5 2else
  17. 17. 33 Fizz x | 15 x | 3 x | 5 else
  18. 18. 55 Buzz x | 15 x | 3 x | 5 else
  19. 19. 45 x | 15 x | 3 x | 5 else Fizz
 Buzz
  20. 20. x Fizz
 Buzz Fizz Buzz x | 15 x | 3 x | 5 xelse
  21. 21. let fizzbuzzer x = if x % 15 = 0 then "FizzBuzz" elif x % 3 = 0 then "Fizz" elif x % 5 = 0 then "Buzz" else string x Conditional F#
  22. 22. let itinerary n = match n with | 0 -> "Rules" | 1 -> "Pattern Matching" | 2 -> "Types" | 3 -> "Higher Order Functions" | _ -> "Farewell" itinerary 1 // val it : string = 
 “Pattern Matching"
  23. 23. — ⽼老⼦子 trans. James Legge,
 道德經, 64 “The journey of a thousand li commences with a single step.”
  24. 24. Pattern Match
  25. 25. x Fizz
 Buzz Fizz Buzz x | 15 x | 3 x | 5 x_ Specific General
  26. 26. let fizzbuzzer x = match x with | x when x % 15 = 0 ->
 "FizzBuzz"
 | x when x % 3 = 0 -> "Fizz"
 | x when x % 5 = 0 -> "Buzz"
 | _ -> string x Pattern Match F#
  27. 27. Pattern Match with Tuples
  28. 28. x | 3,
 x | 5 Fizz
 Buzz Fizz Buzz 0, 0 0, _ _, 0 x_ Specific General
  29. 29. let fizzbuzzer x = match x % 3, x % 5 with | 0, 0 -> "FizzBuzz" | 0, _ -> "Fizz" | _, 0 -> "Buzz" | _ -> string x Pattern Match
 with Tuples F#
  30. 30. x | 3 = 0,
 x | 5 = 0 Fizz
 Buzz Fizz Buzz T, T T, F F, T xF, F
  31. 31. x | 3 = 0,
 x | 5 = 0 x Buzz Fizz F, F F, T T, F Fizz
 BuzzT, T
  32. 32. let fizzbuzzer x = match x % 3 = 0, x % 5 = 0 with | false, false -> string x | false, true -> "Buzz" | true, false -> "Fizz" | true, true -> "FizzBuzz" Pattern Match
 with Tuples F#
  33. 33. let itinerary n = match n with | 0 -> "Rules" | 1 -> "Pattern Matching" | 2 -> "Types" | 3 -> "Higher Order Functions" | _ -> "Farewell" itinerary 2 // val it : string = 
 “Types"
  34. 34. Discriminated Unions
 aka Sum Type
  35. 35. value π type 1 type 2 type 3 type n
  36. 36. int Fizz
 Buzz Fizz Buzz Other
 int fizzbuzzer
  37. 37. 45 fizzbuzzer Fizz
 Buzz
  38. 38. 33 fizzbuzzer Fizz
  39. 39. 55 fizzbuzzer Buzz
  40. 40. 2 fizzbuzzer Other
 2
  41. 41. type FizzBuzzer = | FizzBuzz | Fizz | Buzz | Other of int let fizzbuzzing x = match x % 3 = 0, x % 5 = 0 with | true, true -> FizzBuzz | true, false -> Fizz | false, true -> Buzz | false, false -> Other(x) let fizzbuzzer x = match fizzbuzzing x with | FizzBuzz -> "FizzBuzz" | Fizz -> "Fizz" | Buzz -> "Buzz" | Other(x) -> string x Discriminated
 Union F#
  42. 42. type FizzBuzzer = | FizzBuzz | Fizz | Buzz | Other of int … Discriminated
 Union F#
  43. 43. type FizzBuzzer = | FizzBuzz | Fizz | Buzz | Other of int let fizzbuzzing x = match x % 3 = 0, x % 5 = 0 with | true, true -> FizzBuzz | true, false -> Fizz | false, true -> Buzz | false, false -> Other(x) … Discriminated
 Union F#
  44. 44. … let fizzbuzzing x = match x % 3 = 0, x % 5 = 0 with | true, true -> FizzBuzz | true, false -> Fizz | false, true -> Buzz | false, false -> Other(x) let fizzbuzzer x = match fizzbuzzing x with | FizzBuzz -> "FizzBuzz" | Fizz -> "Fizz" | Buzz -> "Buzz" | Other(x) -> string x Discriminated
 Union F#
  45. 45. … let fizzbuzzer x = match fizzbuzzing x with | FizzBuzz -> "FizzBuzz" | Fizz -> "Fizz" | Buzz -> "Buzz" | Other(x) -> string x Discriminated
 Union F#
  46. 46. type FizzBuzzer = | FizzBuzz | Fizz | Buzz | Other of int let fizzbuzzing x = match x % 3 = 0, x % 5 = 0 with | true, true -> FizzBuzz | true, false -> Fizz | false, true -> Buzz | false, false -> Other(x) let fizzbuzzer x = match fizzbuzzing x with | FizzBuzz -> "FizzBuzz" | Fizz -> "Fizz" | Buzz -> "Buzz" | Other(x) -> string x Discriminated
 Union F#
  47. 47. Complete Active Pattern
  48. 48. value anonymous type 1 type 2 type 3 type n
  49. 49. int anonymous Fizz
 Buzz Fizz Buzz Other
 int
  50. 50. 45 anonymous Fizz
 Buzz
  51. 51. 33 anonymous Fizz
  52. 52. 55 anonymous Buzz
  53. 53. 2 anonymous Other
 2
  54. 54. let (|FizzBuzz|Fizz|Buzz|Other|) x = match x % 3 = 0, x % 5 = 0 with | true, true -> FizzBuzz | true, false -> Fizz | false, true -> Buzz | false, false -> Other(x) let fizzbuzzer x = match x with | FizzBuzz -> "FizzBuzz" | Fizz -> "Fizz" | Buzz -> "Buzz" | Other(x) -> string x Complete
 Active Pattern F#
  55. 55. let (|FizzBuzz|Fizz|Buzz|Other|) x = match x % 3 = 0, x % 5 = 0 with | true, true -> FizzBuzz | true, false -> Fizz | false, true -> Buzz | false, false -> Other(x) … Complete
 Active Pattern F#
  56. 56. … let fizzbuzzer x = match x with | FizzBuzz -> "FizzBuzz" | Fizz -> "Fizz" | Buzz -> "Buzz" | Other(x) -> string x Complete
 Active Pattern F#
  57. 57. let (|FizzBuzz|Fizz|Buzz|Other|) x = match x % 3 = 0, x % 5 = 0 with | true, true -> FizzBuzz | true, false -> Fizz | false, true -> Buzz | false, false -> Other(x) let fizzbuzzer x = match x with | FizzBuzz -> "FizzBuzz" | Fizz -> "Fizz" | Buzz -> "Buzz" | Other(x) -> string x Complete
 Active Pattern F#
  58. 58. Partial Active Pattern
  59. 59. value anonymous Some None
  60. 60. 33 divisible by Some 3
  61. 61. 2 divisible by None 3
  62. 62. let (|DivisibleBy|_|) divisor x = if x % divisor = 0 then Some () else None let fizzbuzzer x = match x with | DivisibleBy 3 & DivisibleBy 5 -> "FizzBuzz" | DivisibleBy 3 -> "Fizz" | DivisibleBy 5 -> "Buzz" | _ -> string x Partial
 Active Pattern F#
  63. 63. let (|DivisibleBy|_|) divisor x = if x % divisor = 0 then Some () else None … Partial
 Active Pattern F#
  64. 64. … let fizzbuzzer x = match x with | DivisibleBy 3 & DivisibleBy 5 -> “FizzBuzz" | DivisibleBy 3 -> “Fizz" | DivisibleBy 5 -> “Buzz" | _ -> string x Partial
 Active Pattern F#
  65. 65. let (|DivisibleBy|_|) divisor x = if x % divisor = 0 then Some () else None let fizzbuzzer x = match x with | DivisibleBy 3 & DivisibleBy 5 -> "FizzBuzz" | DivisibleBy 3 -> "Fizz" | DivisibleBy 5 -> "Buzz" | _ -> string x Partial
 Active Pattern F#
  66. 66. let itinerary n = match n with | 0 -> "Rules" | 1 -> "Pattern Matching" | 2 -> "Types" | 3 -> "Higher Order Functions" | _ -> "Farewell" itinerary 3 // val it : string = 
 “Higher Order Functions"
  67. 67. Fold
  68. 68. statefunction value 1 value 2 value n
  69. 69. statefunction value 2 value 3 value n
  70. 70. statefunction value 3 value 4
  71. 71. statefunction value 4
  72. 72. resultfunction
  73. 73. 0+ 1 2 3
  74. 74. 1+ 2 3 4
  75. 75. 3+ 3 4
  76. 76. 6+ 4
  77. 77. 10+
  78. 78. “”m f -> m ++ f x x | 3 ? Fizz : “” x | 5 ? Buzz : “”
  79. 79. “”m f -> m ++ f 3 3 | 3 ? Fizz : “” x | 5 ? Buzz : “”
  80. 80. Fizzm f -> m ++ f 3 3 | 5 ? Buzz : “” “Fizz”:“”
  81. 81. Fizzm f -> m ++ f 3 “Buzz”:“”
  82. 82. “”m f -> m ++ f 15 15 | 3 ? Fizz : “” x | 5 ? Buzz : “”
  83. 83. Fizzm f -> m ++ f 15 15 | 5 ? Buzz : “” “Fizz”:“”
  84. 84. Fizz
 Buzz m f -> m ++ f 15 “Buzz”:“”
  85. 85. let fizzbuzzer x = let rule d s = (fun x -> if x % d = 0 then s else "") [rule 3 "Fizz"; rule 5 "Buzz"] |> List.fold (fun m f -> m + f x) "" |> (fun s -> if s = "" then string x else s)Fold F#
  86. 86. … let rule d s = (fun x -> if x % d = 0 then s else "") … Fold F#
  87. 87. … let rule d s = (fun x -> if x % d = 0 then s else "") [rule 3 "Fizz"; rule 5 "Buzz"] … Fold F#
  88. 88. … [rule 3 "Fizz"; rule 5 "Buzz"] … Fold F#
  89. 89. … [rule 3 "Fizz"; rule 5 "Buzz"] |> List.fold (fun m f -> m + f x) "" … Fold F#
  90. 90. … |> (fun s -> if s = "" then string x else s) Fold F#
  91. 91. let fizzbuzzer x = let rule d s = (fun x -> if x % d = 0 then s else "") [rule 3 "Fizz"; rule 5 "Buzz"] |> List.fold (fun m f -> m + f x) "" |> (fun s -> if s = "" then string x else s)Fold F#
  92. 92. Zip
  93. 93. function result i result ii result iii result p value 1 value 2 value 3 value n value a value b value c value m
  94. 94. + 11 22 1 2 10 20
  95. 95. ++ Fizz
 Buzz “” “” Fizz Fizz “” “” Fizz Buzz “” “” “”
  96. 96. let fizzbuzzer x = let rec fizz = seq { yield "Fizz"; yield ""; yield ""; yield! fizz } let rec buzz = seq { yield "Buzz"; yield ""; yield ""; yield ""; yield ""; yield! buzz } Seq.map2 (+) fizz buzz |> Seq.item (abs x) |> (fun s -> if s = "" then string x else s) Zip F#
  97. 97. … let rec fizz = seq { yield "Fizz"; yield ""; yield ""; yield! fizz } let rec buzz = seq { yield "Buzz"; yield ""; yield ""; yield ""; yield ""; yield! buzz } … Zip F#
  98. 98. … Seq.map2 (+) fizz buzz … Zip F#
  99. 99. … Seq.map2 (+) fizz buzz |> Seq.item (abs x) … Zip F#
  100. 100. … Seq.map2 (+) fizz buzz |> Seq.item (abs x) |> (fun s -> if s = "" then string x else s) Zip F#
  101. 101. let fizzbuzzer x = let rec fizz = seq { yield "Fizz"; yield ""; yield ""; yield! fizz } let rec buzz = seq { yield "Buzz"; yield ""; yield ""; yield ""; yield ""; yield! buzz } Seq.map2 (+) fizz buzz |> Seq.item (abs x) |> (fun s -> if s = "" then string x else s) Zip F#
  102. 102. let itinerary n = match n with | 0 -> "Rules" | 1 -> "Pattern Matching" | 2 -> "Types" | 3 -> "Higher Order Functions" | _ -> "Farewell" itinerary 4 // val it : string = 
 “Farewell"
  103. 103. — Friedrich Nietzsche trans. R.J. Hollingdale,
 Human, All Too Human, “The Wanderer and His Shadow”, 324 “How can anyone become a thinker if he does not spend at least a third of the day without passions, people, and books?”
  104. 104. Thank you! Mike Harris
 
 @MikeMKH
 http://comp-phil.blogspot.com/
  105. 105. Images • Klamath National Forest, NFS road 16N05 about 8 miles South of Happy Camp, California. Taken by Erik Wheaton, http://www.burningwell.org/gallery2/v/Landscapes/forrests/ 16N05_March_05.jpg.html • View of São Paulo city from Núcleo Pedra Grande in Cantareira State Park. From https:// commons.wikimedia.org/wiki/File:Vista_de_s%C3%A3o_paulo_cantareira.jpg • Centro de São Paulo, Brasil. Taken by Ana Paula Hirama, https://commons.wikimedia.org/wiki/ File:Centro_SP2.jpg • F# logomark, by Unknown at the source. Fair use, https://en.wikipedia.org/w/index.php? curid=44014320 • Lao-Tzu, by Lawrencekhoo - http://www.eng.taoism.org.hk/daoist-beliefs/immortals&immortalism/, Public Domain, https://commons.wikimedia.org/w/index.php?curid=3991827 • Friedrich Nietzsche, by Unknown - http://ora-web.swkk.de/nie_brief_online/nietzsche.digitalisate? id=234&nr=1, Public Domain, https://commons.wikimedia.org/w/index.php?curid=95964 • Me at StrangeLoop 2014. Taken by Kelsey Harris.
  106. 106. Source Code • Conditional
 https://gist.github.com/MikeMKH/9866f9923fa4dfa140e6 • Pattern Matching
 https://gist.github.com/MikeMKH/ 3fe93b2feea575f075fc54aecff2f01c • Pattern Matching with Tuple
 https://gist.github.com/MikeMKH/9b35eb70ffdbcb605efa • Pattern Matching with Tuple using True / False
 https://gist.github.com/MikeMKH/ f0d7f21554500ffc4de60d6acefca4a5
  107. 107. Source Code • Discriminated Union
 https://gist.github.com/MikeMKH/ 05d95775276744c304d2e4e253960aba • Complete Active Pattern
 https://gist.github.com/MikeMKH/ 15a837dbb24053320abb • Partial Active Pattern
 https://gist.github.com/MikeMKH/ a38be4d25641980a8dda
  108. 108. Source Code • Fold
 https://gist.github.com/MikeMKH/ 39dbbc94d963df436c62 • Zip
 https://gist.github.com/MikeMKH/ c107d578d727ba514d05fc8bfa078bb7
  109. 109. Books • Brandewinder, Mathias. Machine learning projects for .NET Developers. Berkeley, CA New York, NY: Apress, 2015. Print. • Fancher, Dave. The book of F♯ : breaking free with managed functional programming. San Francisco: No Starch Press, 2014. Print. • Lipovača, Miran. Learn you a Haskell for great good! a beginner's guide. San Francisco, Calif: No Starch Press, 2011. Print. • Michaelson, Greg. An introduction to functional programming through Lambda calculus. Mineola, N.Y: Dover Publications, 2011. Print.
  110. 110. Websites • Wlaschin, Scoot. F# for Fun and Profit. Web. 16 May 2016. <https://fsharpforfunandprofit.com/>. • Seemann, Mark. ploeh blog. Web. 16 May 2016. < http://blog.ploeh.dk/ >.
  111. 111. Papers • Emir, Burak, Odersky, Martin and Williams, John. Matching Objects With Patterns. LAMP-REPORT-2006-006. • Hutton, Graham. A tutorial on the universality and expressiveness of fold. J. Functional Programming, 9 (4): 355–372, July 1999. • Petricek, Tomas and Syme, Don. The F# Computation Expression Zoo. Proceedings of Practical Aspects of Declarative Languages, PADL 2014. San Diego, CA, USA. • Wadler, Philip. Views︎: A way for pattern matching to cohabit with data abstraction. March ︎︎︎︎1987.

×