Trying to understand Ocaml’s mechanism for named parameters. I understand the basics, but the doc shows an example like this:
# let f ~x ~y = x - y;;
val f : x:int -> y:int -> int = <fun>
# let x = 3 and y = 2 in f ~x ~y;;
- : int = 1
What exactly is going on when only the tilde is used in application? Is it just shorthand for ~x:x, similar to definitions? If so, can someone explain why this:
# ListLabels.fold_left;;
- : f:('a -> 'b -> 'a) -> init:'a -> 'b list -> 'a = <fun>
# let add = (+) and i = 0
in ListLabels.fold_left ~add ~i [1;2;3];;
produces
- : f:((add:(int -> int -> int) -> i:int -> 'a) ->
int -> add:(int -> int -> int) -> i:int -> 'a) ->
init:(add:(int -> int -> int) -> i:int -> 'a) -> 'a = <fun>
The man says
“beware that functions like ListLabels.fold_left whose result type is a type variable will never be considered as totally applied.”
Here is what happens in your example. Beware it’s a bit involved.
is just the classic use:
ListLabels.fold_lefttaks 3 arguments, namely a function labeledf, an initializerinitand a list.Now, in
the application
ListLabels.fold_left ~add ~i [1;2;3]is considered incomplete (as the man says). That means that`ListLabels.fold_leftreceives first its unamed argument,[1;2;3]and returns a function of typef:('a -> int -> 'a) -> init:'a -> 'a. Let us call this function foo.Since you’re giving two named arguments, labeled
addandi, the type'ais inferred to be a functional type, of typeadd:'c -> ~i:'d -> 'e.Based on the type of the variables
addandi, the type'cmust beint -> int -> int, and'dmust beint.Replacing those values in the type
'a, we derive that the type'aisadd:(int -> int -> int) -> i:int -> 'e.And replacing this in the type of foo (I’m glad there is copy-pasting ;-), its type is
Removing unecessary parentheses, and alpha converting (i.e. renaming)
'eto'a, we getThat is the type of foo. But remember that you are passing two arguments to foo, labeled
~addand~i. So the value you get at the end is not of typeadd:(int -> int -> int) -> i:int -> 'abut indeed of type'a. And the whole type of your example is, as returned by the compiler,