(*** Playing with when things happen ***) fun factorial (n : int) : int = if n <= 0 then 1 else n * factorial (n - 1) fun my_if (b : bool, t : 'a, f : 'a) : 'a = if b then t else f fun factorial2 (n : int) : int = my_if (n <= 0, 1, n * factorial2 (n - 1)) fun if_funs (b:bool, t:unit->'a, f:unit->'a) : 'a= if b then t() else f() fun factorial3 (n : int) :int = if_funs (n <= 0, fn () => 1, fn () => n * factorial3 (n - 1)) (*** Playing with Thunks ***) (* Return a function that prints x and then returns it. *) fun print_and_return (x:int) () : int = (print (Int.toString x); print "\n"; x) fun silly_adds () : int = let val a : int = print_and_return 3 () val b : int Thunk.thunk = Thunk.make(print_and_return 4) val c : unit -> int = print_and_return 5 val d : int = c () + (Thunk.apply b) + a val e : int = c () + (Thunk.apply b) + a val f : int = c () + (Thunk.apply b) + a in d + e + f end (* A silly way to take a long time to do something. *) fun slow_add1 (x: int) = let fun slow_id (x : int, y : int) = if(y = 0) then x else slow_id(x, y-1) in (slow_id (x,100000000)) + 1 end val seven_thunk = Thunk.make (fn () => slow_add1 6) (*** Playing with Streams ***) (* Some very simple streams *) val nats = Stream.make (0, fn x => 1 + x) val evens = Stream.make (0, fn x => 2 + x) val alt = Stream.make (true, not) (* Some utilities *) fun stream_first (l : 'a Stream.stream) : 'a = #1 (Stream.next l) fun stream_rest (l : 'a Stream.stream) : 'a Stream.stream = #2 (Stream.next l) fun stream_sum_n (l : int Stream.stream, n : int) : int = if(n = 0) then 0 else (stream_first l) + (stream_sum_n (stream_rest l, n-1)) fun first_n(s: 'a Stream.stream, n: int) : 'a list = if n = 0 then [] else let val (head, tail) = Stream.next(s) in head::first_n(tail, n-1) end val slow_nats = Stream.make(0, slow_add1)