Using Core.Std.List.fold_left without shortcut

I am experimenting with Core List.fold_left

.

# List.fold_left;;
- : 'a Core.Std.List.t -> init:'b -> f:('b -> 'a -> 'b) -> 'b = <fun>

      

It works great when I specify the labels:

# List.fold_left [1;2;3] ~init:0 ~f:(+);;
- : int = 6                  

      

But I get a different result when I do not specify the labels:

# List.fold_left [1;2;3] 0 (+);;
- : init:(int -> (int -> int -> int) -> '_a) ->
    f:((int -> (int -> int -> int) -> '_a) ->
       int -> int -> (int -> int -> int) -> '_a) ->
    '_a
= <fun>

      

And other partial applications also provide non-intuitive types. Why can I add an arbitrary number of 0s after the list argument?

# List.fold_left [1;2;3] 0;;
- : init:(int -> '_a) -> f:((int -> '_a) -> int -> int -> '_a) -> '_a = <fun>

# List.fold_left [1;2;3] 0 0;;
- : init:(int -> int -> '_a) ->
    f:((int -> int -> '_a) -> int -> int -> int -> '_a) -> '_a
= <fun>

      

Several other functions have the same behavior:

# let app ~f ~x = f x;;
val app : f:('a -> 'b) -> x:'a -> 'b = <fun>

# app (fun x -> x + 1) 1;;
- : f:('a -> (int -> int) -> int -> 'b) -> x:'a -> 'b = <fun>

      

However, some labeled functions may return the expected result when applied without the labels specified. For example:

# List.map;;
- : 'a Core.Std.List.t -> f:('a -> 'b) -> 'b Core.Std.List.t = <fun>

# List.map [1;2;3] (fun x -> x + 1);;
- : int Core.Std.List.t = [2; 3; 4]

      

Why do some functions return non-intuitive values ​​when applied without the specified labels, while others work as expected?

+3


source to share


2 answers


According to the manual, you can only omit labels if the application is generic (excluding all optional arguments) "with an important caveat" that functions of a type ListLabels.fold_left

whose result type is a type variable will never be fully applied. "



So, since the result type core fold_left

is of course also a type variable, you cannot call it unlabeled. What happens when you do is that the positional arguments are interpreted as arguments to the function created fold_left

, and it is still waiting for you to supply the flagged arguments.

+4


source


Answer

@ sepp2k explains clearly what's going on here. Let me add one more thing.

Just DO NOT omit the labeled function labels. They are there for purposes. I believe no one can handle the label. You should always turn on warning 6 and make the mistake:



$ ocamlc -w +6 -warn-error +6 file.ml
File "file.ml", line 2, characters 17-18:
Warning 6: labels were omitted in the application of this function.
File "file.ml", line 1:
Error: Some fatal warnings were triggered (1 occurrences)

      

+1


source







All Articles