type 'a llist = LNil | LCons of 'a * 'a llist lazy_t;; let rec ltake n = function | LCons (a, ll) when n > 0 -> a::(ltake (n-1) (Lazy.force ll)) | _ -> [] ;; let rec lfrom n = LCons (n, lazy (lfrom (n+1)));; let rec lfilter f = function | LNil -> LNil | LCons (n, ll) -> if f n then LCons (n, lazy (lfilter f (Lazy.force ll))) else lfilter f (Lazy.force ll) ;; let primes = let rec sieve = function LCons(p,nf) -> LCons(p, lazy (sieve (sift p (Lazy.force nf)))) | LNil -> failwith "Impossible! Internal error." and sift p = lfilter (function n -> n mod p <> 0) in sieve (lfrom 2) ;; let times ll n = lmap (fun i -> i * n) ll;; let rec merge xs ys = match xs, ys with | LCons (x, xr), LCons (y, yr) -> if x < y then LCons (x, lazy (merge (Lazy.force xr) ys)) else if x > y then LCons (y, lazy (merge xs (Lazy.force yr))) else LCons (x, lazy (merge (Lazy.force xr) (Lazy.force yr))) | r, LNil | LNil, r -> r ;; let hamming k = let pr = ltake k primes in let rec h = LCons (1, lazy ( )) in h ;;