Why this code can't get compiled?

open Batteries

let s = Text.of_string
let (&) = Text.append

let rec gen_separated_list (type e) sep (gen : e -> Text.t) (list : e list) : Text.t =
  match list with
  | [] -> s ""
  | e :: [] -> gen e
  | e :: list -> gen e & s sep & gen_separated_list sep gen list
File "test.ml", line 10, characters 56-59:
10 |   | e :: list -> gen e & s sep & gen_separated_list sep gen list
                                                             ^^^
Error: This expression has type e -> Text.t
       but an expression was expected of type 'a
       The type constructor e would escape its scope

Locally abstract types are confined to their scope and gen_separated_list is defined before (type e) is introduced. The smallest fix here is probably:


let gen_separated_list (type e) =
  let rec gen_separated_list sep (gen : e -> Text.t) 
    (list : e list) : Text.t =
    match list with
    | [] -> s ""
    | e :: [] -> gen e
    | e :: list -> gen e & s sep & gen_separated_list sep gen list
  in
  gen_separated_list

Another option is to use an universal quantification to explicit the type of the recursive function inside its body.

  let rec gen_separated_list: type e. _ -> (e -> Text.t) -> e list -> _ = 
   fun sep gen list -> match list with
    | [] -> s ""
    | e :: [] -> gen e
    | e :: list -> gen e & s sep & gen_separated_list sep gen list
3 Likes