Slide 1

Slide 1 text

Folding Inverting a binary tree with a single line of Elm Joël Quenneville @joelquen

Slide 2

Slide 2 text

Joël Quenneville @joelquen

Slide 3

Slide 3 text

Invert a binary tree... Joël Quenneville @joelquen

Slide 4

Slide 4 text

... on a whiteboard! Joël Quenneville @joelquen

Slide 5

Slide 5 text

Joël Quenneville @joelquen

Slide 6

Slide 6 text

fold (\v l r -> Node v r l) Empty Joël Quenneville @joelquen

Slide 7

Slide 7 text

33 chars (61 idiomatic) Joël Quenneville @joelquen

Slide 8

Slide 8 text

How does this work? Joël Quenneville @joelquen

Slide 9

Slide 9 text

Tree overview Joël Quenneville @joelquen

Slide 10

Slide 10 text

Defining a binary tree type Tree a = Empty | Node a (Tree a) (Tree a) Joël Quenneville @joelquen

Slide 11

Slide 11 text

myTree : Tree Int myTree = Empty Joël Quenneville @joelquen

Slide 12

Slide 12 text

myTree : Tree Int myTree = Node 1 Empty Empty Joël Quenneville @joelquen

Slide 13

Slide 13 text

myTree : Tree Int myTree = Node 1 (Node 2 Empty Empty) (Node 3 Empty Empty) Joël Quenneville @joelquen

Slide 14

Slide 14 text

myTree : Tree Int myTree = Node 1 (Node 2 (Node 4 Empty Empty) (Node 5 Empty Empty) ) (Node 3 Empty (Node 6 Empty Empty) ) Joël Quenneville @joelquen

Slide 15

Slide 15 text

Joël Quenneville @joelquen

Slide 16

Slide 16 text

What is "inverting"? Joël Quenneville @joelquen

Slide 17

Slide 17 text

Flip horizontally Joël Quenneville @joelquen

Slide 18

Slide 18 text

Joël Quenneville @joelquen

Slide 19

Slide 19 text

→ Left children are red Joël Quenneville @joelquen

Slide 20

Slide 20 text

→ Left children are red → Right children are green Joël Quenneville @joelquen

Slide 21

Slide 21 text

6 ↔ Empty Joël Quenneville @joelquen

Slide 22

Slide 22 text

5 ↔ 4 Joël Quenneville @joelquen

Slide 23

Slide 23 text

3 ↔ 2 Joël Quenneville @joelquen

Slide 24

Slide 24 text

Back to the one-liner Joël Quenneville @joelquen

Slide 25

Slide 25 text

What is fold? fold (\v l r -> Node v r l) Empty yourTree Joël Quenneville @joelquen

Slide 26

Slide 26 text

fold : (a -> b -> b -> b) -> b -> Tree a -> b Joël Quenneville @joelquen

Slide 27

Slide 27 text

fold : (a -> b -> b -> b) -- ??? -> b -- ??? -> Tree a -- tree being folded -> b -- return value Joël Quenneville @joelquen

Slide 28

Slide 28 text

Mental models Joël Quenneville @joelquen

Slide 29

Slide 29 text

Reducing Joël Quenneville @joelquen

Slide 30

Slide 30 text

Reducing Constructor Replacement Joël Quenneville @joelquen

Slide 31

Slide 31 text

Reducing Constructor Replacement Abstraction over Recursion Joël Quenneville @joelquen

Slide 32

Slide 32 text

Reducing Many → Aggregate Joël Quenneville @joelquen

Slide 33

Slide 33 text

Sum → 21 Joël Quenneville @joelquen

Slide 34

Slide 34 text

Count → 6 Joël Quenneville @joelquen

Slide 35

Slide 35 text

Min → 1 Joël Quenneville @joelquen

Slide 36

Slide 36 text

fold : (a -> b -> b -> b) -- aggregation -> b -- start accumulator -> Tree a -> b Joël Quenneville @joelquen

Slide 37

Slide 37 text

Aggregating function add3 : Int -> Int -> Int -> Int add3 currentVal leftAcc rightAcc = currentVal + leftAcc + rightAcc Joël Quenneville @joelquen

Slide 38

Slide 38 text

Summing a tree fold add3 -- aggregation 0 -- start accumulator tree Joël Quenneville @joelquen

Slide 39

Slide 39 text

Further discussion → What other common operations can be described as aggregations of a collection? Joël Quenneville @joelquen

Slide 40

Slide 40 text

Tree → Tree? Joël Quenneville @joelquen

Slide 41

Slide 41 text

Constructor Replacement Joël Quenneville @joelquen

Slide 42

Slide 42 text

type Tree a = Node a (Tree a) (Tree a) | Empty Joël Quenneville @joelquen

Slide 43

Slide 43 text

Signatures type Tree a = Node a (Tree a) (Tree a) -- a -> Tree a -> Tree a -> Tree a | Empty -- Tree a Joël Quenneville @joelquen

Slide 44

Slide 44 text

Replace Tree a with b type Tree a = Node a (Tree a) (Tree a) -- a -> b -> b -> b | Empty -- b Joël Quenneville @joelquen

Slide 45

Slide 45 text

fold : (a -> b -> b -> b) -> b -> Tree a -> b Joël Quenneville @joelquen

Slide 46

Slide 46 text

Coincidence? Joël Quenneville @joelquen

Slide 47

Slide 47 text

fold : (a -> b -> b -> b) -- Replace Node -> b -- Replace Empty -> Tree a -> b Joël Quenneville @joelquen

Slide 48

Slide 48 text

add3 : Int -> Int -> Int -> Int add3 a b c = a + b + c Joël Quenneville @joelquen

Slide 49

Slide 49 text

Summing a tree Tree.fold add3 -- replace Node with add3 0 -- replace Empty with 0 someTree Joël Quenneville @joelquen

Slide 50

Slide 50 text

Node 1 (Node 2 (Node 4 Empty Empty) Empty ) (Node 3 Empty Empty) Joël Quenneville @joelquen

Slide 51

Slide 51 text

add3 1 (add3 2 (add3 4 Empty Empty) Empty ) (add3 3 Empty Empty) Joël Quenneville @joelquen

Slide 52

Slide 52 text

add3 1 (add3 2 (add3 4 0 0) 0 ) (add3 3 0 0) Joël Quenneville @joelquen

Slide 53

Slide 53 text

add3 1 (add3 2 (add3 4 0 0) -- 4 0 ) (add3 3 0 0) Joël Quenneville @joelquen

Slide 54

Slide 54 text

add3 1 (add3 2 -- | 4 -- | 6 0 -- | ) (add3 3 0 0) Joël Quenneville @joelquen

Slide 55

Slide 55 text

add3 1 6 (add3 3 0 0) -- 3 Joël Quenneville @joelquen

Slide 56

Slide 56 text

add3 1 --| 6 --| 10 3 --| Joël Quenneville @joelquen

Slide 57

Slide 57 text

Folding new trees Joël Quenneville @joelquen

Slide 58

Slide 58 text

fold Node -- replace Node with Node Empty -- replace Empty with Empty someTree Joël Quenneville @joelquen

Slide 59

Slide 59 text

Lesson: We can use fold to disassemble and rebuild a tree Joël Quenneville @joelquen

Slide 60

Slide 60 text

node : a -> Tree a -> Tree a -> Tree a node value left right = Node value left right Joël Quenneville @joelquen

Slide 61

Slide 61 text

inverseNode : a -> Tree a -> Tree a -> Tree a inverseNode value left right = Node value right left Joël Quenneville @joelquen

Slide 62

Slide 62 text

Tree.fold inverseNode -- replace Node with inverseNode Empty -- replace Empty with Empty someTree Joël Quenneville @joelquen

Slide 63

Slide 63 text

Node 1 (Node 2 (Node 4 Empty Empty) Empty ) (Node 3 Empty Empty) Joël Quenneville @joelquen

Slide 64

Slide 64 text

inverseNode 1 (inverseNode 2 (inverseNode 4 Empty Empty) Empty ) (inverseNode 3 Empty Empty) Joël Quenneville @joelquen

Slide 65

Slide 65 text

inverseNode 1 (inverseNode 2 (inverseNode 4 Empty Empty) -- swap two empties Empty ) (inverseNode 3 Empty Empty) -- swap two empties Joël Quenneville @joelquen

Slide 66

Slide 66 text

inverseNode 1 (inverseNode 2 (Node 4 Empty Empty) -- swap this Empty -- with this ) (Node 3 Empty Empty) Joël Quenneville @joelquen

Slide 67

Slide 67 text

inverseNode 1 (Node 2 Empty (Node 4 Empty Empty) ) (Node 3 Empty Empty) Joël Quenneville @joelquen

Slide 68

Slide 68 text

inverseNode 1 (Node 2 -- | Empty -- | swap this (Node 4 Empty Empty) -- | ) (Node 3 Empty Empty) -- with this Joël Quenneville @joelquen

Slide 69

Slide 69 text

Node 1 (Node 3 Empty Empty) (Node 2 Empty (Node 4 Empty Empty) ) Joël Quenneville @joelquen

Slide 70

Slide 70 text

Success! Joël Quenneville @joelquen

Slide 71

Slide 71 text

Further discussion → How can this technique be applied to other data structures? Joël Quenneville @joelquen

Slide 72

Slide 72 text

Recursion Joël Quenneville @joelquen

Slide 73

Slide 73 text

Pseudocode IF EMPTY your_base_case ELSE RECURSE LEFT RECURSE RIGHT your_action Joël Quenneville @joelquen

Slide 74

Slide 74 text

Abstraction over recursion fold : (a -> b -> b -> b) -- action to do recursively -> b -- base case -> Tree a -- tree -> b -- return Joël Quenneville @joelquen

Slide 75

Slide 75 text

fold inverseNode -- recursively inverse node Empty -- base case tree Joël Quenneville @joelquen

Slide 76

Slide 76 text

fold : (a -> b -> b -> b) -> b -> Tree a -> b fold fn baseCase tree = case tree of Node val left right -> fn val (fold fn baseCase left) (fold fn baseCase right) Empty -> baseCase Joël Quenneville @joelquen

Slide 77

Slide 77 text

Layers of abstraction Joël Quenneville @joelquen

Slide 78

Slide 78 text

Further discussion → What other abstractions might built on top of recursion? Joël Quenneville @joelquen

Slide 79

Slide 79 text

Summary Joël Quenneville @joelquen

Slide 80

Slide 80 text

3 Perspectives on those args fold : (a -> b -> b -> b) -- ??? -> b -- ??? -> Tree a -> b Joël Quenneville @joelquen

Slide 81

Slide 81 text

Reducing 1. Aggregation 2. Initial accumulator Joël Quenneville @joelquen

Slide 82

Slide 82 text

Constructor replacement 1. Replaces Node 2. Replaces Empty Joël Quenneville @joelquen

Slide 83

Slide 83 text

Recursion 1. Recursive case 2. Base case Joël Quenneville @joelquen

Slide 84

Slide 84 text

Invert a binary tree in 1 line of Elm fold (\v l r -> Node v r l) Empty tree Joël Quenneville @joelquen