All You Need is Fold

132
All You Need is Fold Mike Harris

Transcript of All You Need is Fold

Page 1: All You Need is Fold

All You Need is Fold Mike Harris

Page 2: All You Need is Fold

All You Need Is FOLD

Page 3: All You Need is Fold

All You Need Is FOLD

Page 4: All You Need is Fold

All you need is FOLD

Page 5: All You Need is Fold

FOLD

Page 6: All You Need is Fold

Fold is All You Need!

Page 7: All You Need is Fold

Tour

• Backstage

• Concert

• Farewell

Page 8: All You Need is Fold

Backstage

Page 9: All You Need is Fold

f

g

Function

Page 10: All You Need is Fold

f g

f(g)

Function

Page 11: All You Need is Fold

Fold

a1

a2

an

b

Page 12: All You Need is Fold

Fold

foldr :: (α → β → β) → β → ([α] → β)foldl :: (β → α→ β) → β → ([α] → β)

SeedFunc

a1

a2

an

Fold b

Given

We

Func

Seed

Page 13: All You Need is Fold

f anf a2f Seed a1

Page 14: All You Need is Fold

f anf a2f(Seed, a1)

Page 15: All You Need is Fold

f anf(f(Seed, a1), a2)

Page 16: All You Need is Fold

b

Page 17: All You Need is Fold

Fold

a1

a2

an

b

Page 18: All You Need is Fold

— Paul FeyerabendAgainst Method Chapter 16

“Fundamental conceptual change … presupposes new world-views and

new languages capable of expressing them.”

Page 19: All You Need is Fold

Concert

All You Need is Fold

Page 20: All You Need is Fold

Set List

• And

• Or

• Length

• Reverse

• Map

• Filter

• Zip

Page 21: All You Need is Fold

Set List

• And

• Or

• Length

• Reverse

• Map

• Filter

• Zip

Page 22: All You Need is Fold

And

T/F

T/F

T/F

T/F

Page 23: All You Need is Fold

And

and :: [Bool] → Booland = fold (∧) True

TrueAnd

f1

f2

fn

Fold f

Given

We

And

True

Page 24: All You Need is Fold

And

True And

Page 25: All You Need is Fold

foldAnd = (...facts) => { _.foldl(

facts, (m, x) => m && x, true);

};And True

Page 26: All You Need is Fold

foldAnd(false, true, false);

Page 27: All You Need is Fold

And

True

False True False

And

Page 28: All You Need is Fold

And

True

False True False

M

X

result False

And

Page 29: All You Need is Fold

And

False

True False

M

X

result False

And

Page 30: All You Need is Fold

And

False

False

M

X

result False

And

Page 31: All You Need is Fold

And

True

False True False

result False

And

Page 32: All You Need is Fold

foldAnd = (...facts) => { _.foldl(

facts, (m, x) => m && x, true);

};And True

Page 33: All You Need is Fold

Set List

• And

• Or

• Length

• Reverse

• Map

• Filter

• Zip

Page 34: All You Need is Fold

Or

T/F

T/F

T/F

T/F

Page 35: All You Need is Fold

Or

or :: [Bool] → Boolor = fold (∨) False

FalseOr

f1

f2

fn

Fold f

Given

We

Or

False

Page 36: All You Need is Fold

Or

False Or

Page 37: All You Need is Fold

foldOr = (...facts) => { _.foldl(

facts, (m, x) => m || x, false);

};Or False

Page 38: All You Need is Fold

foldOr(false, true, false);

Page 39: All You Need is Fold

Or

False

False True False

Or

Page 40: All You Need is Fold

Or

False

False True False

M

X

result False

Or

Page 41: All You Need is Fold

Or

False

True False

M

X

result True

Or

Page 42: All You Need is Fold

Or

True

False

M

X

result True

Or

Page 43: All You Need is Fold

Or

False

False True False

result True

Or

Page 44: All You Need is Fold

foldOr = (...facts) => { _.foldl(

facts, (m, x) => m || x, false);

};Or False

Page 45: All You Need is Fold

Set List

• And

• Or

• Length

• Reverse

• Map

• Filter

• Zip

Page 46: All You Need is Fold

Length size

Page 47: All You Need is Fold

Length

length :: [α] → Intlength = fold (λx n → 1 + n) 0

0+ 1

x1

x2

xn

Fold #

Given

We

+ 1

0

Page 48: All You Need is Fold

+ 1

0 Length

Page 49: All You Need is Fold

foldLength = (coll) => { _.foldl(

coll, m => m + 1, 0);

};+ 1 0

Page 50: All You Need is Fold

foldLength([…'Mike']);

Page 51: All You Need is Fold

+ 1

0

M i k e

Length

Page 52: All You Need is Fold

+ 1

0M

result 1

M i k e

Length

Page 53: All You Need is Fold

+ 1

1M

result 2

i k e

Length

Page 54: All You Need is Fold

+ 1

2M

result 3

k e

Length

Page 55: All You Need is Fold

+ 1

3M

result 4

e

Length

Page 56: All You Need is Fold

+ 1

0

result 4

M i k e

Length

Page 57: All You Need is Fold

foldLength = (coll) => { _.foldl(

coll, m => m + 1, 0);

};+ 1 0

Page 58: All You Need is Fold

Set List

• And

• Or

• Length

• Reverse

• Map

• Filter

• Zip

Page 59: All You Need is Fold

Reverse

x1

x2

xn

xn

x2

x1

Page 60: All You Need is Fold

Reverse

reverse :: [α] → [α]reverse = fold (λx m → m ++ [x]) [ ]

[ ]Cons

x1

x2

xn

Fold [x]

Given

We

Cons

[ ]

Page 61: All You Need is Fold

Cons

[ ] Reverse

Page 62: All You Need is Fold

foldReverse = (coll) => { _.foldl(

coll, (m, x) => { m.unshift(x); return m; },

[]); }; Cons [ ]

Page 63: All You Need is Fold

foldReverse([…'Mike']);

Page 64: All You Need is Fold

Cons

[ ]

M i k e

Reverse

Page 65: All You Need is Fold

Cons

[ ]

M i k

M

X

result M

e

Reverse

Page 66: All You Need is Fold

Cons

M

i k e

M

X

result iM

Reverse

Page 67: All You Need is Fold

Cons

iM

k e

M

X

result kiM

Reverse

Page 68: All You Need is Fold

Cons

kiM

e

M

X

result ekiM

Reverse

Page 69: All You Need is Fold

Cons

[ ]

result ekiM

M i k e

Reverse

Page 70: All You Need is Fold

foldReverse = (coll) => { _.foldl(

coll, (m, x) => { m.unshift(x); return m; },

[]); }; Cons [ ]

Page 71: All You Need is Fold

Set List

• And

• Or

• Length

• Reverse

• Map

• Filter

• Zip

Page 72: All You Need is Fold

Map

x1

x2

xn

z1

z2

zn

func

Page 73: All You Need is Fold

Map

map :: (α → β) → ([α] → [β])map f = fold (λx xs → f x : xs) [ ]

[ ]Conj

x1

x2

xn

Fold [z]

Given

We

Conj

[ ]

Page 74: All You Need is Fold

Conj

[ ]

func

Map

Page 75: All You Need is Fold

foldMap = (f, coll) => { _.foldl(

coll, (m, x) => { m.push(f(x)); return m; },

[]); }; Conj [ ]

Page 76: All You Need is Fold

foldMap( s => s.toUpperCase(), […'Mike']);

Page 77: All You Need is Fold

Conj

[ ]

M i k e

upper

Map

Page 78: All You Need is Fold

Conj

[ ]

M i k

M

X

result M

e

upper

Map

Page 79: All You Need is Fold

Conj

M

i k e

M

X

result MIupper

Map

Page 80: All You Need is Fold

Conj

MI

k e

M

X

result MIKupper

Map

Page 81: All You Need is Fold

Conj

MIK

e

M

X

result MIKEupper

Map

Page 82: All You Need is Fold

Conj

[ ]

M i k

result

e

upper MIKE

Map

Page 83: All You Need is Fold

foldMap = (f, coll) => { _.foldl(

coll, (m, x) => { m.push(f(x)); return m; },

[]); }; Conj [ ]

Page 84: All You Need is Fold

Set List

• And

• Or

• Length

• Reverse

• Map

• Filter

• Zip

Page 85: All You Need is Fold

Filter

x1

x2

xn

x1

xn

pred

Page 86: All You Need is Fold

Filter

filter :: (α → Bool) → ([α] → [α])filter p = fold (λx xs → if p x then x : xs else xs) [ ]

if

Conj

[ ]

x1

x2

xn

Fold [x]

Given

We

[ ]

if

Conj

Page 87: All You Need is Fold

if

[ ]

pred Conj

Filter

Page 88: All You Need is Fold

foldFilter = (pred, coll) => { _.foldl(

coll, (m, x) => { if (pred(x)) m.push(x); return m; },

[]); }; [ ]if Conj

Page 89: All You Need is Fold

foldFilter( s => /^[a-z]*$/.test(s), […'Mike']);

Page 90: All You Need is Fold

if

[ ]

M i k e

isLower Conj

Filter

Page 91: All You Need is Fold

if

[ ]

M i k

M

X

result [ ]

e

isLower Conj

Filter

Page 92: All You Need is Fold

if

[ ]

i k e

M

X

isLower result iConj

Filter

Page 93: All You Need is Fold

if

i

k e

M

X

isLower result ikConj

Filter

Page 94: All You Need is Fold

if

ik

e

M

X

isLower result ikeConj

Filter

Page 95: All You Need is Fold

if

[ ]

isLower

M i k e

result ikeConj

Filter

Page 96: All You Need is Fold

foldFilter = (pred, coll) => { _.foldl(

coll, (m, x) => { if (pred(x)) m.push(x); return m; },

[]); }; [ ]if Conj

Page 97: All You Need is Fold

Set List

• And

• Or

• Length

• Reverse

• Map

• Filter

• Zip

Page 98: All You Need is Fold

Zip

y1

y2

yj

z1

z2

zk

funcx1

x2

xi

Page 99: All You Need is Fold

Zip

zip2 :: (α → β → γ) → ([α] → [β] → [γ])zip2 f = fold (λx y xs ys → f x y : xs ys) [ ]

[ ]Conj

y1

y2

ym

Fold [z]

Given

We

Conj

[ ]

x1

x2

xn

Page 100: All You Need is Fold

Conj

[ ]

func

Zip

Page 101: All You Need is Fold

foldZip = (f, xs, ys) => { _.foldl(

_.zip(xs, ys), (m, [x, y]) => { m.push(f(x, y)); return m; },

[]); }; Conj [ ]

Page 102: All You Need is Fold

foldZip( _.add, [1, 2], [10, 20]);

Page 103: All You Need is Fold

Conj

[ ]

1 2

+

10 20

Zip

Page 104: All You Need is Fold

Conj

[ ]

1 2

+

10 20

M

result 11

X

Y

Zip

Page 105: All You Need is Fold

Conj

11

2

+

20

M

result 11 22

X

Y

Zip

Page 106: All You Need is Fold

Conj

[ ]

+ result 11 22

1 2

10 20

Zip

Page 107: All You Need is Fold

foldZip = (f, xs, ys) => { _.foldl(

_.zip(xs, ys), (m, [x, y]) => { m.push(f(x, y)); return m; },

[]); }; Conj [ ]

Page 108: All You Need is Fold

Encore

Coin Changer

Page 109: All You Need is Fold

Change

coin1

coin2

coinn

c1

c2

cn

amount

Page 110: All You Need is Fold

Coin Changer kata

changeFor :: [α] → α → [α]changeFor a = fold (λa x xs → (a % x, a / x) : xs (a, [ ])

Conj

Changer

[ ]

amount

c1

c2

cn

Fold

Given

We

[c]

0

Conj

Changer

[ ]

amount

Page 111: All You Need is Fold

Conj

amount [ ]

Changer

Change

Page 112: All You Need is Fold

foldChange = (coins, amount) => { _.foldl(coins,

(m, coin) => { m.result.push( _.floor(m.result / coin)); m.amount %= coin; return m;

},{amount: amount, result: []}).result;

};Conj [ ]

Changer amount

Page 113: All You Need is Fold

foldChange( [25, 10, 5, 1], 99);

Page 114: All You Need is Fold

Conj

amount

25 10 5 1

[ ]

Changer

Change

Page 115: All You Need is Fold

Conj

99

25 10 5 1

[ ]M

X

result 24 3Changer

Change

Page 116: All You Need is Fold

Conj

24

10 5 1

3M

X

result 4 3 2Changer

Change

Page 117: All You Need is Fold

Conj

4

5 1

3 2M

X

result 4 3 2 0Changer

Change

Page 118: All You Need is Fold

Conj

4

1

3 2 0M

X

result 0 3 2 0 4Changer

Change

Page 119: All You Need is Fold

Conj result 0 3 2 0 4Changer

amount [ ]

25 10 5 1

Change

Page 120: All You Need is Fold

foldChange = (coins, amount) => { _.foldl(coins,

(m, coin) => { m.result.push( _.floor(m.result / coin)); m.amount %= coin; return m;

},{amount: amount, result: []}).result;

};Conj [ ]

Changer amount

Page 121: All You Need is Fold

— Paul FeyerabendAgainst Method Chapter 18

“[A]ll methodologies, even the most obvious ones, have their limits”

Page 122: All You Need is Fold
Page 123: All You Need is Fold
Page 124: All You Need is Fold
Page 125: All You Need is Fold

Thank you!

Mike Harris@MikeMKHhttp://comp-phil.blogspot.com/Remember, all you need is Fold!

Page 126: All You Need is Fold

Talks

• Rich Hickey - “Reducers”, EuroClojure 2012. https://vimeo.com/45561411

• Rich Hickey - “Transducers”, StrangeLoop 2014. https://www.youtube.com/watch?v=6mTbuzafcII

• Tomas Petricek - “History and Philosophy of Types”, StrangeLoop 2015. http://tpetricek.github.io/Talks/2015/philosophy-of-types/#/

Page 127: All You Need is Fold

Books

• Richard Bird and Phil Wadler - Introduction to Functional Programming. Prentice-Hall,1988.http://usi-pl.github.io/lc/sp-2015/doc/Bird_Wadler.%20Introduction%20to%20Functional%20Programming.1ed.pdf

• Paul Feyerabend - Against Method. Verso, 2010.

• Michael Fogus - Functional JavaScript: Introducing Functional Programming with Underscore.js. O’Reilly, 2013.http://functionaljavascript.com/

Page 128: All You Need is Fold

Papers

• Erik Meijer, Maarten Fokkinga, and Ross Paterson - “Functional Programming with Bananas, Lenses, Envelopes and Barbed Wire”. http://eprints.eemcs.utwente.nl/7281/01/db-utwente-40501F46.pdf

• Graham Hutton - “A tutorial on the universality and expressiveness of fold”.http://www.cs.nott.ac.uk/~gmh/fold.pdf

Page 129: All You Need is Fold

Blog Posts

• Brian McNamara - “Catamorphisms, part one”https://lorgonblog.wordpress.com/2008/04/05/catamorphisms-part-one/

• Edward Kmett - “Catamorphisms”https://www.fpcomplete.com/user/edwardk/recursion-schemes/catamorphisms

Page 130: All You Need is Fold

Websites

• ClojureDocs - https://clojuredocs.org/

• HaskellWiki - https://wiki.haskell.org/Haskell

• Inside F# - https://lorgonblog.wordpress.com/

• lodash - https://lodash.com/docs

• MDN - https://developer.mozilla.org/en-US/

• ReactiveX - http://reactivex.io/

Page 131: All You Need is Fold

Images (in order used)• "Abbey Rd Studios" by Misterweiss at en.wikipedia - Transfered from en.wikipedia Transfer was stated to be made by User:Blast..

Licensed under Public Domain via Commons - https://commons.wikimedia.org/wiki/File:Abbey_Rd_Studios.jpg#/media/File:Abbey_Rd_Studios.jpg

• "60s wallpaper" by Domincspics - Flickr. Licensed under CC BY 2.0 via Commons - https://commons.wikimedia.org/wiki/File:60s_wallpaper.jpg#/media/File:60s_wallpaper.jpg

• "70's Wallpaper" by Liz Sullivan - Own work. Licensed under CC BY-SA 4.0 via Wikimedia Commons - https://commons.wikimedia.org/wiki/File:70%27s_Wallpaper.JPG#/media/File:70%27s_Wallpaper.JPG

• "Flickr - ronsaunders47 - The Beatles-Sgt Pepper backdrop.". Licensed under CC BY-SA 2.0 via Wikimedia Commons - https://commons.wikimedia.org/wiki/File:Flickr_-_ronsaunders47_-_The_Beatles-Sgt_Pepper_backdrop..jpg#/media/File:Flickr_-_ronsaunders47_-_The_Beatles-Sgt_Pepper_backdrop..jpg

• "All you need is love graffiti Osijek" by Objavljeno - Own work. Licensed under CC BY-SA 3.0 via Wikimedia Commons - https://commons.wikimedia.org/wiki/File:All_you_need_is_love_graffiti_Osijek.JPG#/media/File:All_you_need_is_love_graffiti_Osijek.JPG

• "Illumined Pleasure Salvador Dali" by Salvador Dalí - Own workMrArifnajafov (Photography from the original). Licensed under CC BY-SA 3.0 via Wikimedia Commons - https://commons.wikimedia.org/wiki/File:Illumined_Pleasure_Salvador_Dali.JPG#/media/File:Illumined_Pleasure_Salvador_Dali.JPG

• "3 Savile Row" by Original uploader was Misterweiss at en.wikipedia - Transfered from en.wikipedia Transfer was stated to be made by User:Vinhtantran.. Licensed under Public Domain via Commons - https://commons.wikimedia.org/wiki/File:3_Savile_Row.jpg#/media/File:3_Savile_Row.jpg

• "Paul Feyerabend 2" by Grazia Borrini-Feyerabend. Licensed under Attribution via Commons - https://commons.wikimedia.org/wiki/File:Paul_Feyerabend_2.jpg#/media/File:Paul_Feyerabend_2.jpg

Page 132: All You Need is Fold

Images (in order used)• "The Beatles on Green Hill in Almaty, Kazakhstan" by Ken and Nyetta - Flickr: The Beatles on

Green Hill in Almaty. Licensed under CC BY 2.0 via Commons - https://commons.wikimedia.org/wiki/File:The_Beatles_on_Green_Hill_in_Almaty,_Kazakhstan.jpg#/media/File:The_Beatles_on_Green_Hill_in_Almaty,_Kazakhstan.jpg

• "The Beatles in America" by United Press International, photographer unknown - This image is available from the United States Library of Congress's Prints and Photographs division under the digital ID cph.3c11094.This tag does not indicate the copyright status of the attached work.

• "The Beatles rooftop concert" by Source. Licensed under Fair use via Wikipedia - https://en.wikipedia.org/wiki/File:The_Beatles_rooftop_concert.jpg#/media/File:The_Beatles_rooftop_concert.jpg

• "Paul Feyerabend 2" by Grazia Borrini-Feyerabend. Licensed under Attribution via Commons - https://commons.wikimedia.org/wiki/File:Paul_Feyerabend_2.jpg#/media/File:Paul_Feyerabend_2.jpg

• Myself taken at StrangeLoop 2014 by my wife, Kelsey Harris