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.
Próximos SlideShares
Carregando em…5
×

# Hiking through the Functional Forest with Fizz Buzz

794 visualizações

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.

• Full Name
Comment goes here.

Are you sure you want to Yes No
• 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 Speciﬁc 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 Speciﬁc 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_ Speciﬁc 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_ Speciﬁc 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 ﬁzzbuzzer
37. 37. 45 ﬁzzbuzzer Fizz  Buzz
38. 38. 33 ﬁzzbuzzer Fizz
39. 39. 55 ﬁzzbuzzer Buzz
40. 40. 2 ﬁzzbuzzer 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 Proﬁt. Web. 16 May 2016. <https://fsharpforfunandproﬁt.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.