Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Inverting a Binary Tree in One Line of Elm

Inverting a Binary Tree in One Line of Elm

Joël Quenneville talks about Inverting a binary tree with 1 line of Elm at the Elm Online Meetup on September 1st 2021.

https://www.youtube.com/watch?v=dSMB3rsufC8

Joël Quenneville

September 01, 2021
Tweet

More Decks by Joël Quenneville

Other Decks in Programming

Transcript

  1. fold (\v l r -> Node v r l) Empty

    Joël Quenneville @joelquen
  2. Defining a binary tree type Tree a = Empty |

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

    Joël Quenneville @joelquen
  4. myTree : Tree Int myTree = Node 1 (Node 2

    Empty Empty) (Node 3 Empty Empty) Joël Quenneville @joelquen
  5. 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
  6. What is fold? fold (\v l r -> Node v

    r l) Empty yourTree Joël Quenneville @joelquen
  7. fold : (a -> b -> b -> b) ->

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

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

    aggregation -> b -- start accumulator -> Tree a -> b Joël Quenneville @joelquen
  10. Aggregating function add3 : Int -> Int -> Int ->

    Int add3 currentVal leftAcc rightAcc = currentVal + leftAcc + rightAcc Joël Quenneville @joelquen
  11. Summing a tree fold add3 -- aggregation 0 -- start

    accumulator tree Joël Quenneville @joelquen
  12. Further discussion → What other common operations can be described

    as aggregations of a collection? Joël Quenneville @joelquen
  13. type Tree a = Node a (Tree a) (Tree a)

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

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

    a (Tree a) (Tree a) -- a -> b -> b -> b | Empty -- b Joël Quenneville @joelquen
  16. fold : (a -> b -> b -> b) ->

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

    Replace Node -> b -- Replace Empty -> Tree a -> b Joël Quenneville @joelquen
  18. add3 : Int -> Int -> Int -> Int add3

    a b c = a + b + c Joël Quenneville @joelquen
  19. Summing a tree Tree.fold add3 -- replace Node with add3

    0 -- replace Empty with 0 someTree Joël Quenneville @joelquen
  20. Node 1 (Node 2 (Node 4 Empty Empty) Empty )

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

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

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

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

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

    Quenneville @joelquen
  26. fold Node -- replace Node with Node Empty -- replace

    Empty with Empty someTree Joël Quenneville @joelquen
  27. Lesson: We can use fold to disassemble and rebuild a

    tree Joël Quenneville @joelquen
  28. node : a -> Tree a -> Tree a ->

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

    Tree a inverseNode value left right = Node value right left Joël Quenneville @joelquen
  30. Tree.fold inverseNode -- replace Node with inverseNode Empty -- replace

    Empty with Empty someTree Joël Quenneville @joelquen
  31. Node 1 (Node 2 (Node 4 Empty Empty) Empty )

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

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

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

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

    (Node 3 Empty Empty) Joël Quenneville @joelquen
  36. inverseNode 1 (Node 2 -- | Empty -- | swap

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

    4 Empty Empty) ) Joël Quenneville @joelquen
  38. Further discussion → How can this technique be applied to

    other data structures? Joël Quenneville @joelquen
  39. Abstraction over recursion fold : (a -> b -> b

    -> b) -- action to do recursively -> b -- base case -> Tree a -- tree -> b -- return Joël Quenneville @joelquen
  40. 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
  41. Further discussion → What other abstractions might built on top

    of recursion? Joël Quenneville @joelquen
  42. 3 Perspectives on those args fold : (a -> b

    -> b -> b) -- ??? -> b -- ??? -> Tree a -> b Joël Quenneville @joelquen
  43. Invert a binary tree in 1 line of Elm fold

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