infinite data structures
play

Infinite Data Structures! CS 51 and CSCI E-51 March 25, 2014 . - PowerPoint PPT Presentation

Infinite Data Structures! CS 51 and CSCI E-51 March 25, 2014 . let head (Cons(x, _) : a stream) : a = x let tail (Cons(_, r) : a stream) : a stream = r A first attempt Consider this definition for infinite sequences: We can


  1. Infinite Data Structures! CS 51 and CSCI E-51 March 25, 2014 .

  2. let head (Cons(x, _) : ’a stream) : ’a = x let tail (Cons(_, r) : ’a stream) : ’a stream = r A first attempt Consider this definition for infinite sequences: We can extract the head and the tail of a stream: But how can we build one? type ’a stream = Cons of ’a * ’a stream 2:1

  3. A first attempt Consider this definition for infinite sequences: We can extract the head and the tail of a stream: But how can we build one? type ’a stream = Cons of ’a * ’a stream let head (Cons(x, _) : ’a stream) : ’a = x let tail (Cons(_, r) : ’a stream) : ’a stream = r 2:2

  4. A first attempt Consider this definition for infinite sequences: We can extract the head and the tail of a stream: But how can we build one? type ’a stream = Cons of ’a * ’a stream let head (Cons(x, _) : ’a stream) : ’a = x let tail (Cons(_, r) : ’a stream) : ’a stream = r 2:3

  5. utop[5] head ones - : int = 1 utop[6] head (tail ones) - : int = 1 utop[7] head (tail (tail ones)) - : int = 1 But how can we build one? Recursion! let rec ones = Cons(1, ones) 3:1

  6. utop[6] head (tail ones) - : int = 1 utop[7] head (tail (tail ones)) - : int = 1 But how can we build one? Recursion! let rec ones = Cons(1, ones) utop[5] head ones - : int = 1 3:2

  7. utop[7] head (tail (tail ones)) - : int = 1 But how can we build one? Recursion! let rec ones = Cons(1, ones) utop[5] head ones - : int = 1 utop[6] head (tail ones) - : int = 1 3:3

  8. But how can we build one? Recursion! let rec ones = Cons(1, ones) utop[5] head ones - : int = 1 utop[6] head (tail ones) - : int = 1 utop[7] head (tail (tail ones)) - : int = 1 3:4

  9. let rec ones = Cons(1, let rec ones = Cons(1, ones) in ones) let rec ones = Cons(1, Cons(1, let rec ones = Cons(1, ones) in ones)) let rec ones = Cons(1, Cons(1, Cons(1, let rec ones = Cons(1, ones) in ones))) utop[8]> phys_equal ones (tail ones) - : bool = true What it means Reduction-substitution model: . . . Also, this isn’t true: let rec ones = Cons(1, ones) 4:1

  10. let rec ones = Cons(1, Cons(1, let rec ones = Cons(1, ones) in ones)) let rec ones = Cons(1, Cons(1, Cons(1, let rec ones = Cons(1, ones) in ones))) utop[8]> phys_equal ones (tail ones) - : bool = true What it means Reduction-substitution model: . . . Also, this isn’t true: let rec ones = Cons(1, ones) let rec ones = Cons(1, let rec ones = Cons(1, ones) in ones) 4:2

  11. let rec ones = Cons(1, Cons(1, Cons(1, let rec ones = Cons(1, ones) in ones))) utop[8]> phys_equal ones (tail ones) - : bool = true What it means Reduction-substitution model: . . . Also, this isn’t true: let rec ones = Cons(1, ones) let rec ones = Cons(1, let rec ones = Cons(1, ones) in ones) let rec ones = Cons(1, Cons(1, let rec ones = Cons(1, ones) in ones)) 4:3

  12. utop[8]> phys_equal ones (tail ones) - : bool = true What it means Reduction-substitution model: . . . Also, this isn’t true: let rec ones = Cons(1, ones) let rec ones = Cons(1, let rec ones = Cons(1, ones) in ones) let rec ones = Cons(1, Cons(1, let rec ones = Cons(1, ones) in ones)) let rec ones = Cons(1, Cons(1, Cons(1, let rec ones = Cons(1, ones) in ones))) 4:4

  13. What it means Reduction-substitution model: . . . Also, this isn’t true: let rec ones = Cons(1, ones) let rec ones = Cons(1, let rec ones = Cons(1, ones) in ones) let rec ones = Cons(1, Cons(1, let rec ones = Cons(1, ones) in ones)) let rec ones = Cons(1, Cons(1, Cons(1, let rec ones = Cons(1, ones) in ones))) utop[8]> phys_equal ones (tail ones) - : bool = true 4:5

  14. – . – let rec onetwothrees = Cons(1, Cons(2, Cons(3, onetwothrees))) . 1 .. 2 .. 3 .. What’s really happening . . . . . . How about a stream that doesn’t repeat, like the natural numbers? let rec ones = Cons(1, ones) 5:1

  15. let rec onetwothrees = Cons(1, Cons(2, Cons(3, onetwothrees))) . 1 .. 2 .. 3 .. What’s really happening . . . . . . . How about a stream that doesn’t repeat, like the natural numbers? let rec ones = Cons(1, ones) – . – 5:2

  16. let rec onetwothrees = Cons(1, Cons(2, Cons(3, onetwothrees))) . 1 .. 2 .. 3 .. What’s really happening . . . . . . . How about a stream that doesn’t repeat, like the natural numbers? let rec ones = Cons(1, ones) 1 . – 5:3

  17. let rec onetwothrees = Cons(1, Cons(2, Cons(3, onetwothrees))) . 1 .. 2 .. 3 .. What’s really happening How about a stream that doesn’t repeat, like the natural numbers? . . . . . . . . let rec ones = Cons(1, ones) 1 .. 5:4

  18. What’s really happening How about a stream that doesn’t repeat, like the natural numbers? . . . . . . . . . let rec ones = Cons(1, ones) 1 .. let rec onetwothrees = Cons(1, Cons(2, Cons(3, onetwothrees))) . 1 .. 2 .. 3 .. 5:5

  19. What’s really happening How about a stream that doesn’t repeat, like the natural numbers? . . . . . . . . . let rec ones = Cons(1, ones) 1 .. let rec onetwothrees = Cons(1, Cons(2, Cons(3, onetwothrees))) . 1 .. 2 .. 3 .. 5:6

  20. let nats = count_from 0 A stream of natural numbers? Unfortunately, this just recurs until it blows the stack let rec count_from n = Cons(n, count_from (n + 1)) 6:1

  21. A stream of natural numbers? Unfortunately, this just recurs until it blows the stack let rec count_from n = Cons(n, count_from (n + 1)) let nats = count_from 0 6:2

  22. A stream of natural numbers? Unfortunately, this just recurs until it blows the stack let rec count_from n = Cons(n, count_from (n + 1)) let nats = count_from 0 6:3

  23. — To Emacs — 7:1

  24. type ’a stream = ’a str promise ref and ’a str = { hd : ’a; tl : ’a stream } let rec ones = ref (Unevaluated (fun () -> { hd = 1; tl = ones })) let rec head (s : ’a stream) : ’a = match !s with | Evaluated str -> str.hd | Unevaluated f -> let str = f () in s := Evaluated str; str.hd let rec tail (s : ’a stream) : ’a stream = match !s with | Evaluated str -> str.tl | Unevaluated f -> let str = f () in s := Evaluated str; str.tl Take three: memoize the thunks type ’a promise = Unevaluated of (unit -> ’a) | Evaluated of ’a 8:1

  25. let rec ones = ref (Unevaluated (fun () -> { hd = 1; tl = ones })) let rec head (s : ’a stream) : ’a = match !s with | Evaluated str -> str.hd | Unevaluated f -> let str = f () in s := Evaluated str; str.hd let rec tail (s : ’a stream) : ’a stream = match !s with | Evaluated str -> str.tl | Unevaluated f -> let str = f () in s := Evaluated str; str.tl Take three: memoize the thunks type ’a promise = Unevaluated of (unit -> ’a) | Evaluated of ’a type ’a stream = ’a str promise ref and ’a str = { hd : ’a; tl : ’a stream } 8:2

  26. let rec head (s : ’a stream) : ’a = match !s with | Evaluated str -> str.hd | Unevaluated f -> let str = f () in s := Evaluated str; str.hd let rec tail (s : ’a stream) : ’a stream = match !s with | Evaluated str -> str.tl | Unevaluated f -> let str = f () in s := Evaluated str; str.tl Take three: memoize the thunks type ’a promise = Unevaluated of (unit -> ’a) | Evaluated of ’a type ’a stream = ’a str promise ref and ’a str = { hd : ’a; tl : ’a stream } let rec ones = ref (Unevaluated (fun () -> { hd = 1; tl = ones })) 8:3

  27. let rec tail (s : ’a stream) : ’a stream = match !s with | Evaluated str -> str.tl | Unevaluated f -> let str = f () in s := Evaluated str; str.tl Take three: memoize the thunks type ’a promise = Unevaluated of (unit -> ’a) | Evaluated of ’a type ’a stream = ’a str promise ref and ’a str = { hd : ’a; tl : ’a stream } let rec ones = ref (Unevaluated (fun () -> { hd = 1; tl = ones })) let rec head (s : ’a stream) : ’a = match !s with | Evaluated str -> str.hd | Unevaluated f -> let str = f () in s := Evaluated str; str.hd 8:4

  28. Take three: memoize the thunks type ’a promise = Unevaluated of (unit -> ’a) | Evaluated of ’a type ’a stream = ’a str promise ref and ’a str = { hd : ’a; tl : ’a stream } let rec ones = ref (Unevaluated (fun () -> { hd = 1; tl = ones })) let rec head (s : ’a stream) : ’a = match !s with | Evaluated str -> str.hd | Unevaluated f -> let str = f () in s := Evaluated str; str.hd let rec tail (s : ’a stream) : ’a stream = match !s with | Evaluated str -> str.tl | Unevaluated f -> let str = f () in s := Evaluated str; str.tl 8:5

  29. let force (pr : ’a my_lazy_t) : ’a = match !pr with | Evaluated v -> v | Unevaluated f -> let v = f () in pr := Evaluated v; v type ’a stream = ’a str my_lazy_t and ’a str = { hd : ’a; tl : ’a stream } let head (s : ’a stream) : ’a = (force s).hd let tail (s : ’a stream) : ’a stream = (force s).tl let rec map (s : ’a stream) ~(f : ’a -> ’b) : ’b stream = ref (Unevaluted (fun () -> { hd = f (head s); tl = map (tail s) ~f })) The laziness pattern type ’a promise = Unevaluated of (unit -> ’a) | Evaluated of ’a type ’a my_lazy_t = ’a promise ref 9:1

Recommend


More recommend