Skip to content

Instantly share code, notes, and snippets.

@ScriptDevil
Created July 15, 2020 07:39
Show Gist options
  • Save ScriptDevil/1baf46c1b784c0c1822af62059091631 to your computer and use it in GitHub Desktop.
Save ScriptDevil/1baf46c1b784c0c1822af62059091631 to your computer and use it in GitHub Desktop.
let namedf ~first:a ~second:b = (a,b);;
let f a b = (a,b);;
(*
val namedf : first:'a -> second:'b -> 'a * 'b = <fun>
val f : 'a -> 'b -> 'a * 'b = <fun>
*)
let partialnamedf = namedf ~first:33;;
let partialf = f 33;;
(*
val partialnamedf : second:'_weak2 -> int * '_weak2 = <fun>
val partialf : '_weak3 -> int * '_weak3 = <fun>
*)
let named_tuple_appl = partialnamedf 42;;
let tuple_appl = partialf 42;;
(*
val named_tuple_appl : int * int = (33, 42)
val tuple_appl : int * int = (33, 42)
*)
let tuple_pipe = 42 |> partialf;;
(* val tuple_pipe : int * int = (33, 42) *)
let named_tuple_pipe = 42 |> partialnamedf;;
(*
val tuple_pipe : int * int = (33, 42)
File "mycode.ml", line 43, characters 29-42:
43 | let named_tuple_pipe = 42 |> partialnamedf;;
^^^^^^^^^^^^^
Error: This expression has type second:int -> int * int
but an expression was expected of type int -> 'a
*)
@ScriptDevil
Copy link
Author

ScriptDevil commented Jul 15, 2020

Turns out we cannot elide labels when passing to higher order functions like |>

From https://caml.inria.fr/pub/docs/manual-ocaml/lablexamples.html When a function is passed as an argument to a higher-order function, labels must match in both types. Neither adding nor removing labels are allowed.

Workarounds:

  1. Use a lambda:
42 |> (fun x -> partialnamedf ~second:f)
  1. Use https://github.com/janestreet/ppx_pipebang

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment