Is it possible to combine pipe operator with labeled argument?

Currently I have some code like

   let result_tmp1 =
     replace_all (create "dataUrl") ~in_:result ~with_:"\"dataUrl\""
   in
   let result_tmp2 =
     replace_all (create "pages") ~in_:result_tmp1 ~with_:"\"pages\""
   in
   let result_final =
     replace_all (create "data:") ~in_:result_tmp2 ~with_:"\"data\":"
   in

And I tried to make it pipe as follows

...
  |> replace_all (create "dataUrl") ~with_:"\"dataUrl\""
  |> replace_all (create "pages") ~with_:"\"pages\""
  |> replace_all (create "data:") ~with_:"\"data\":"

Got error:

Error: The function applied to this argument has type in_:string -> string
This argument cannot be applied without label
1 Like

Hi @Taki.

In general, it’s not possible to pipe into a function with a labelled argument. You could eta-expand around each call to replace_all:

...
  |> (fun in_ -> replace_all (create "dataUrl") ~with_:"\"dataUrl\"" ~in_)
  |> (fun in_ -> replace_all (create "pages") ~with_:"\"pages\"" ~in_)
  |> (fun in_ -> replace_all (create "data:") ~with_:"\"data\":" ~in_)

or you could drop the label ~in_ entirely from the definition of replace_all. For this reason, even label-heavy libraries like those from Jane Street tend to avoid labelling at least one of the arguments to each function in order to support partial application.


Related aside: when a function application is saturated – i.e. it is known to not return a function – it’s possible to omit argument labels. Naturally this will never happen for pipe sequences, which rely on partial application on the RHS of the pipes. Even still, I recommend avoiding this language feature for the sake of consistency.

2 Likes

Awesome thanks, actually the function replace_all is from JaneStreet

I’ll try to use Str.global_replace , in that case we could avoid the labels.

1 Like

You could do something like the following so that you can still use the pipe but without switching to a different function:

let _ =
  let repl s ~pat ~with_ = String.Search_pattern.replace_all (create pat) ~in_:s ~with_ in
  result
  |> repl ~pat:"dataUrl" ~with_:"\"dataUrl\""
  |> repl ~pat:"pages"   ~with_:"\"pages\""
  |> repl ~pat:"data:"   ~with_:"\"data\":"
2 Likes