Hiking through the Functional Forest with Fizz Buzz

115
Hiking through the Functional Forest with FizzBuzz Mike Harris | @MikeMKH | comp-phil.blogspot.com

Transcript of Hiking through the Functional Forest with Fizz Buzz

Hiking through the Functional Forest with FizzBuzz

Mike Harris | @MikeMKH | comp-phil.blogspot.com

The Functional Forest and Object Oriented City

The Functional Forest and Object Oriented City

let itinerary n = match n with | 0 -> "Rules" | 1 -> "Pattern Matching" | 2 -> "Types" | 3 -> "Higher Order Functions" | _ -> "Farewell"

// val itinerary : n:int -> string

let itinerary n = match n with | 0 -> "Rules" | 1 -> "Pattern Matching" | 2 -> "Types" | 3 -> "Higher Order Functions" | _ -> "Farewell" itinerary 0

// val it : string = “Rules"

FizzBuzz

number FizzBuzzer text

int int -> string string

Rules

• x | 3 and x | 5 => FizzBuzz• x | 3 => Fizz• x | 5 => Buzz• x => string x

Rules

• x | 3 and x | 5 => FizzBuzz

• x | 3 => Fizz

• x | 5 => Buzz

• x => string x

Specific

General

2 FizzBuzzer 2

x

33 FizzBuzzer Fizz

x | 3

55 FizzBuzzer Buzz

x | 5

45 FizzBuzzer FizzBuzz

x | 3

Conditional

xFizzBuzz

Fizz

Buzz

x | 15

x | 3

x | 5

xelse

Specific

General

2

x | 15

x | 3

x | 5

2else

33

Fizz

x | 15

x | 3

x | 5

else

55

Buzz

x | 15

x | 3

x | 5

else

45

x | 15

x | 3

x | 5

else

FizzBuzz

xFizzBuzz

Fizz

Buzz

x | 15

x | 3

x | 5

xelse

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#

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"

— ⽼老⼦子 trans. James Legge,道德經, 64

“The journey of a thousand li commences with a single step.”

Pattern Match

xFizzBuzz

Fizz

Buzz

x | 15

x | 3

x | 5

x_

Specific

General

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#

Pattern Match with Tuples

x | 3, x | 5

FizzBuzz

Fizz

Buzz

0, 0

0, _

_, 0

x_

Specific

General

let fizzbuzzer x = match x % 3, x % 5 with | 0, 0 -> "FizzBuzz" | 0, _ -> "Fizz" | _, 0 -> "Buzz" | _ -> string x

Pattern Matchwith Tuples

F#

x | 3 = 0,x | 5 = 0

FizzBuzz

Fizz

Buzz

T, T

T, F

F, T

xF, F

x | 3 = 0,x | 5 = 0

x

Buzz

Fizz

F, F

F, T

T, F

FizzBuzzT, T

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 Matchwith Tuples

F#

let itinerary n = match n with | 0 -> "Rules" | 1 -> "Pattern Matching" | 2 -> "Types" | 3 -> "Higher Order Functions" | _ -> "Farewell" itinerary 2

// val it : string = “Types"

Discriminated Unions aka Sum Type

value πtype 1

type 2

type 3

type n

int

FizzBuzz

Fizz

Buzz

Other int

fizzbuzzer

45 fizzbuzzer FizzBuzz

33 fizzbuzzer Fizz

55 fizzbuzzer Buzz

2 fizzbuzzer Other 2

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

DiscriminatedUnion

F#

type FizzBuzzer = | FizzBuzz | Fizz | Buzz | Other of int …

DiscriminatedUnion

F#

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#

… 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#

… let fizzbuzzer x = match fizzbuzzing x with | FizzBuzz -> "FizzBuzz" | Fizz -> "Fizz" | Buzz -> "Buzz" | Other(x) -> string x

DiscriminatedUnion

F#

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

DiscriminatedUnion

F#

Complete Active Pattern

value anonymous

type 1

type 2

type 3

type n

int anonymous

FizzBuzz

Fizz

Buzz

Other int

45 anonymous FizzBuzz

33 anonymous Fizz

55 anonymous Buzz

2 anonymous Other 2

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#

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) …

CompleteActive Pattern

F#

… let fizzbuzzer x = match x with | FizzBuzz -> "FizzBuzz" | Fizz -> "Fizz" | Buzz -> "Buzz" | Other(x) -> string x

CompleteActive Pattern

F#

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#

Partial Active Pattern

value anonymous

Some

None

33 divisible by Some

3

2 divisible by None

3

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#

let (|DivisibleBy|_|) divisor x = if x % divisor = 0 then Some () else None …

PartialActive Pattern

F#

… let fizzbuzzer x = match x with | DivisibleBy 3 & DivisibleBy 5 -> “FizzBuzz"

| DivisibleBy 3 -> “Fizz"

| DivisibleBy 5 -> “Buzz"

| _ -> string xPartialActive Pattern

F#

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#

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"

Fold

statefunction value 1

value 2

value n

statefunction value 2

value 3

value n

statefunction value 3

value 4

statefunction value 4

resultfunction

0+ 1

2

3

1+ 2

3

4

value

3+ 3

4

value

6+ 4

10+

“”m f -> m ++ f x x | 3 ? Fizz : “”

x | 5 ? Buzz : “”

“”m f -> m ++ f 3 3 | 3 ? Fizz : “”

x | 5 ? Buzz : “”

Fizzm f -> m ++ f 3 3 | 5 ? Buzz : “”

“Fizz”:“”

Fizzm f -> m ++ f 3

“Buzz”:“”

“”m f -> m ++ f 15 15 | 3 ? Fizz : “”

x | 5 ? Buzz : “”

Fizzm f -> m ++ f 15 15 | 5 ? Buzz : “”

“Fizz”:“”

FizzBuzzm f -> m ++ f 15

“Buzz”:“”

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#

… let rule d s = (fun x -> if x % d = 0 then s else "") …

Fold

F#

… let rule d s = (fun x -> if x % d = 0 then s else "")

[rule 3 "Fizz"; rule 5 "Buzz"] …

Fold

F#

… [rule 3 "Fizz"; rule 5 "Buzz"] …

Fold

F#

… [rule 3 "Fizz"; rule 5 "Buzz"] |> List.fold (fun m f -> m + f x) "" …

Fold

F#

… |> (fun s -> if s = "" then string x else s)

Fold

F#

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#

Zip

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

+

11

22

1

2

10

20

++

FizzBuzz

“”

“”

Fizz

Fizz

“”

“”

Fizz

Buzz

“”

“”

“”

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#

… let rec fizz = seq { yield "Fizz"; yield ""; yield ""; yield! fizz }

let rec buzz = seq { yield "Buzz"; yield ""; yield ""; yield ""; yield ""; yield! buzz } …

Zip

F#

… Seq.map2 (+) fizz buzz …

Zip

F#

… Seq.map2 (+) fizz buzz |> Seq.item (abs x) …

Zip

F#

… Seq.map2 (+) fizz buzz |> Seq.item (abs x) |> (fun s -> if s = "" then string x else s)

Zip

F#

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#

let itinerary n = match n with | 0 -> "Rules" | 1 -> "Pattern Matching" | 2 -> "Types" | 3 -> "Higher Order Functions" | _ -> "Farewell" itinerary 4

// val it : string = “Farewell"

— 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?”

Thank you!

Mike Harris@MikeMKHhttp://comp-phil.blogspot.com/

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.

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

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

Source Code

• Foldhttps://gist.github.com/MikeMKH/39dbbc94d963df436c62

• Ziphttps://gist.github.com/MikeMKH/c107d578d727ba514d05fc8bfa078bb7

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.

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/ >.

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.