I'm trying to learn ocaml but ran into an issue with the function composition operator |>.
utop # #require "core";;
utop # open Core;;
utop # Option.value_exn(Some(1));;
- : int = 1
utop # Some(1) |> Option.value_exn;;
Error: This expression has type
?here:Base__Source_code_position0.t ->
?error:Base.Error.t -> ?message:string -> 'a option -> 'a
but an expression was expected of type int option -> 'b
I thoght x |> f
was supposed to be equivalent to f(x)
. Why does Option.value_exn(Some(1))
work but not Some(1) |> Option.value_exn
?
No, they aren't equivalent. You can define |>
operator as:
utop # let (|>) a f = f a;;
val ( |> ) : 'a -> ('a -> 'b) -> 'b = <fun>
So, it expects some value of type 'a
and a function 'a -> 'b
.
But, type of Option.value_exn
is not 'a -> 'b
due to named parameters:
utop # Option.value_exn;;
- : ?here:Lexing.position ->
?error:Base.Error.t -> ?message:string -> 'a option -> 'a
You can specify all named parameters explicitly (makes zero sense actually)
utop # Some 1 |> Option.value_exn ~here:Lexing.dummy_pos ~error:(Error.of_string "dummy") ~message:"dummy";;
- : int = 1
or just use lambda to wrap it
utop # Some 1 |> fun x -> Option.value_exn x;;
- : int = 1
The difficulties with type inference and optional/labeled arguments is described in the Ocaml manual. It mentions that the right way to resolve the issue is to give an explicit type ascription for the troublesome argument, in this case Option.value_exn
. Indeed
Some(1) |> (Option.value_exn : int option -> int);;
works. The manual further explains that
in the specific case where the expected type is a non-labeled function type, and the argument is a function expecting optional parameters, the compiler will attempt to transform the argument to have it match the expected type, by passing None for all optional parameters
but it appears that the polymorphism of Option.value_exn
interferes with this mechanism. Evidence that it is the polymoprhism that causes the trouble is seen in the failure of
let f ?(message = "") x = x in 1 |> f;;
for the same reason.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With