My code is:
type 'a llist = LNil | LCons of 'a * 'a llist Lazy.t;;
let rec lfrom k = LCons (k, lazy (lfrom (k+1)));;
let rec toLazyList = function
[] -> LNil
| x::xs -> LCons(x, lazy (toLazyList xs))
;;
let rec ltake = function
(0, _) -> []
| (_, LNil) -> []
| (n, LCons(x, lazy xs)) -> x :: ltake(n-1, xs)
;;
let rec lzip (lxs, lys) =
match (lxs, lys) with
(LCons(h1, lazy t1),LCons(h2, lazy t2)) -> LCons((h1, h2), lazy (lzip (t1, t2)))
| _ -> LNil
;;
let lrepeat k ll =
if k < 1 then failwith "Number less than 1"
else
let rec helper (rpts, rest) = match (rpts, rest) with
(_, LNil) -> LNil
| (0, LCons(_, tl)) -> helper(k, Lazy.force tl)
| (_, LCons(hd, _)) -> LCons(hd, lazy (helper(rpts - 1, rest)))
in helper (k, ll)
Then I do:
> let x = toLazyList([3;4;5]);;
> val x : int llist = LCons (3, <lazy>)
> lrepeat 3 x;;
> int llist = LCons (3, <lazy>)
But how to display a LazyList?
A lazy list might be infinite, so in general, it is not a good idea to print it all. Usually, one takes some finite prefix and collects it into a finite list. You even have a corresponding function implemented, using you own code,
# ltake (3,x);;
- : int list = [3; 4; 5]
A side note, you shall use currying for ltake
so that it should work as ltake 3 x
.