Issue with labeled argument

This line of OCaml:

let c ~f = f() in let () = c (fun () -> ()) in ()

leads to the following error on the c (fun () -> ()) expression:

File "", line 1, characters 27-43:
Error: This expression has type f:(unit -> (unit -> unit) -> 'a) -> 'a
       but an expression was expected of type unit

Without the ~, there is no error. How is the ~ messing things up?

This is fixed by passing the argument with an explicit label:

let c ~f = f() in let () = c ~f:(fun () -> ()) in ()

The reason you can’t omit the label is because the application of c is not considered to be fully applied. This can be a surprise when the return type of a function with labelled arguments is a type variable, which is the case for c.

To make it quite clear: when you pass (fun () -> ()) the return type of c is being inferred as a function type, and the argument is being passed to that function.

1 Like

Thanks, @gsg. I also got a detailed answer about what’s going on here.