ocamlocaml-batteries

int function error in lazy fold_right definition


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 Nils:

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 ints in the code? What am I not seeing?

(Cons, Nil, and next are all defined for LazyList in batLazyList.ml.)


Solution

  • 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