(* option -rectypes requise *)
type 'a delayed = unit -> 'a;;
type 'a stream = 'a option * ( ('a stream ) delayed);;
let rec nullstream = (None, fun () -> nullstream ) ;;
let rec print_stream = function
| (None, f) -> ()
| (Some a, f) -> let _ = print_int a in let _ = print_string "\n" in (print_stream (f () ) );;
let rec stream_constant v = (Some v, fun () -> stream_constant v);;
let rec stream_enum a b = if a = b
then (Some a, fun () -> nullstream)
else (Some a, fun () -> stream_enum (a+1) b);;
let stream_sum s=
let rec f acc = function
| (None, fu) -> (None, fu)
| (Some i, fu) -> let s = i + acc in (Some s, fun () -> f s (fu () ))
in f 0 s;;
(* print_stream (stream_sum (stream_enum 1 19));; *)
let rec stream_map f = function
| (None, fu) -> (None, fu)
| (Some i, fu) -> (Some (f i), fun () -> stream_map f (fu ()) );;
(* print_stream (stream_map (fun a -> a*2) (stream_enum 1 10));; *)