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.
6. let itinerary n =
match n with
| 0 -> "Rules"
| 1 -> "Pattern Matching"
| 2 -> "Types"
| 3 -> "Higher Order Functions"
| _ -> "Farewell"
// val itinerary : n:int -> string
7. let itinerary n =
match n with
| 0 -> "Rules"
| 1 -> "Pattern Matching"
| 2 -> "Types"
| 3 -> "Higher Order Functions"
| _ -> "Farewell"
itinerary 0
// val it : string =
“Rules"
29. 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#
31. x | 3,
x | 5
Fizz
Buzz
Fizz
Buzz
0, 0
0, _
_, 0
x_
Specific
General
32. let fizzbuzzer x =
match x % 3, x % 5 with
| 0, 0 -> "FizzBuzz"
| 0, _ -> "Fizz"
| _, 0 -> "Buzz"
| _ -> string x
Pattern Match
with Tuples
F#
33. x | 3 = 0,
x | 5 = 0
Fizz
Buzz
Fizz
Buzz
T, T
T, F
F, T
xF, F
34. x | 3 = 0,
x | 5 = 0
x
Buzz
Fizz
F, F
F, T
T, F
Fizz
BuzzT, T
35. 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#
36. let itinerary n =
match n with
| 0 -> "Rules"
| 1 -> "Pattern Matching"
| 2 -> "Types"
| 3 -> "Higher Order Functions"
| _ -> "Farewell"
itinerary 2
// val it : string =
“Types"
44. 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#
45. type FizzBuzzer =
| FizzBuzz
| Fizz
| Buzz
| Other of int
…
Discriminated
Union
F#
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)
… Discriminated
Union
F#
47. …
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#
48. …
let fizzbuzzer x =
match fizzbuzzing x with
| FizzBuzz -> "FizzBuzz"
| Fizz -> "Fizz"
| Buzz -> "Buzz"
| Other(x) -> string x
Discriminated
Union
F#
49. 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#
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. 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#
59. …
let fizzbuzzer x =
match x with
| FizzBuzz -> "FizzBuzz"
| Fizz -> "Fizz"
| Buzz -> "Buzz"
| Other(x) -> string x
Complete
Active Pattern
F#
60. 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#
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#
67. …
let fizzbuzzer x =
match x with
| DivisibleBy 3 &
DivisibleBy 5 -> “FizzBuzz"
| DivisibleBy 3 -> “Fizz"
| DivisibleBy 5 -> “Buzz"
| _ -> string x
Partial
Active Pattern
F#
68. 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#
69. 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"
88. 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#
89. …
let rule d s =
(fun x -> if x % d = 0
then s
else "")
…
Fold
F#
90. …
let rule d s =
(fun x -> if x % d = 0
then s
else "")
[rule 3 "Fizz";
rule 5 "Buzz"]
…
Fold
F#
93. …
|> (fun s -> if s = ""
then string x
else s)
Fold
F#
94. 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#
103. …
Seq.map2 (+) fizz buzz
|> Seq.item (abs x)
|> (fun s -> if s = ""
then string x
else s)
Zip
F#
104. 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#
105. let itinerary n =
match n with
| 0 -> "Rules"
| 1 -> "Pattern Matching"
| 2 -> "Types"
| 3 -> "Higher Order Functions"
| _ -> "Farewell"
itinerary 4
// val it : string =
“Farewell"
106.
107. — 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?”
109. 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.
110. 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
111. 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
113. 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.
114. 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/ >.
115. 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.