I'm trying to write a modified version of Batteries.LazyList.lazy_fold_right
. I want a similar function that folds on two lazy lists rather than one lazy list. However, I'm getting an error that doesn't make any sense to me.
Here is the original Batteries definition I started from, in batLazyList.ml:
let lazy_fold_right f l init =
let rec aux rest = lazy begin
match next rest with
| Cons (x, t) -> f x (aux t)
| Nil -> Lazy.force init
end in
aux l
Here's my version:
let lazy_fold_right2 f l1 l2 init =
let open Batteries.LazyList in
let rec aux rest1 rest2 =
lazy begin
match next rest1, next rest2 with
| Cons (x1, t1), Cons (x2, t2) -> f x1 x2 (aux t1 t2)
| Nil, Nil | Nil, _ | _, Nil -> Lazy.force init
end
in
aux l1 l2
The error is on the variable init
at the end of the line with multiple Nil
s:
Error: This expression has type int -> (int -> 'a) -> 'a t but an expression was expected of type 'b lazy_t
Huh? Where is there anything related to int
s in the code? What am I not seeing?
(Cons
, Nil
, and next
are all defined for LazyList
in batLazyList.ml.)
The error comes from the init
function in Batteries.LazyList
that shadows the local init
variable. Two possibilities to avoid the problem are either to activate the warning 44 (for shadowed local identifiers) or define a short alias for Batteries.LazyList
rather than a local open:
let lazy_fold_right2 f l1 l2 init =
let module L = Batteries.LazyList in
let rec aux rest1 rest2 =
lazy begin
match L.next rest1, L.next rest2 with
| L.Cons (x1, t1), Cons (x2, t2) -> f x1 x2 (aux t1 t2)
| Nil, Nil | Nil, _ | _, Nil -> Lazy.force init
end
in
aux l1 l2