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?
source to share
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.
source to share
@ 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)
source to share