open Lazy (******************************************************) (**** PART 1 -- An introduction to the lazy module ****) (******************************************************) (* add function that prints the integers being added *) let add x y = print_string "Adding "; print_int x; print_string " and "; print_int y; print_string "\n"; x + y;; let z1 = 3;; let z2 = 3;; (* normal(eager) add *) let eager_add = add z1 8;; (* Using explicit thunk *) let lazy_add1 = fun() -> (add z1 8);; let z1 = 9;; lazy_add1();; (* The printing occurs a second time. To fix this we would need a new type * that carries a bool with the thunk so we know if the thunk has been * evauated --> The lazy module *) lazy_add1();; (* Using the lazy module also means nicer syntax *) let lazy_add2 = lazy (add z2 8);; (* Evaluating the lazy thunk after changing the value of z does not affect the value of the expression. The value of z is bound to the value it had when the lazy thunk was created. *) let z2 = 9;; Lazy.force lazy_add2;; (* Evaluating a second time returns the cached value and does not print *) Lazy.force lazy_add2;; (******************************************) (**** PART 2 -- A lazy list definition ****) (******************************************) (* Here is one way to define a lazy list in ocaml *) type 'a node_t = | Empty | Node of 'a * 'a node_t Lazy.t;; (********************************************) (**** PART 3 -- Defining some lazy lists ****) (********************************************) (* The infinite list of naturals *) let increment x = x + 1 (* 1,2,3,...+inf*) let rec naturals_helper x = lazy (Node (x, (naturals_helper (increment x)))) let naturals = lazy(Node (1, (naturals_helper (increment 1))));; (* Example stopping criterion -- take n *) let rec takeN l_list n = lazy ( if n == 0 then Empty else (match (Lazy.force l_list) with Node(h,t) -> Node(h, (takeN t (n - 1))) | Empty -> Empty) );; (* The lazy list of fibonacci numbers *) let rec fibonacci_helper p1 p2 = lazy( if p2 = 0 then Node (1, (fibonacci_helper 0 1)) else Node ((p1 + p2), (fibonacci_helper p2 (p1+p2))) ) let fibonacci = lazy (Node (0, (fibonacci_helper 0 0)));; (*************************************************) (**** PART 4 -- Partial module for lazy lists ****) (*************************************************) (* A map function for lazy lists *) let rec map f zlst = lazy ( match Lazy.force zlst with | Empty -> Empty | Node(h, t) -> Node(f h, map f t) );; (* A filter function for lazy lists *) let rec filter f l_list = lazy (match (Lazy.force l_list) with Empty -> Empty | Node (h,t) -> (if (f h) then Node (h, (filter f t)) else (filter_helper f l_list)) ) and filter_helper f l_list = (match (Lazy.force l_list) with Empty -> Empty | Node (h,t) -> (if (f h) then Node (h, (filter f t)) else (filter_helper f l_list)) )