Pipe into a Pipe-First Call?

I’ve got a chain going that looks like this:

  let postData = (uri, data) =>
    inst->Instance.postData(uri, data) |> Promise.Js.fromBsPromise->Promise.Js.map(_x => "")

That fails because I’m assuming it’s trying to evaluate my -> before piping and executing the fromBsPromise function. I get this error:

I can fix it by doing this, but I was wondering if there’s a point-free way to achieve the same thing? Thanks in advance!

  let postData = (uri, data) =>
    inst->Instance.postData(uri, data)
      |> (x => Promise.Js.fromBsPromise(x)->Promise.Js.map(_x => ""))

I figured out in this case, I can just not hop into a |> and just keep it with ->. In general though, is there a way to solve what I was going for above?

  let postData = (uri, data) =>
    inst->Instance.postData(uri, data)->Promise.Js.fromBsPromise->Promise.Js.map(_x => "")

Why do you want to use the |> operator in the first place?

ReScript is the first language I’ve used that has pipe first so my instinct is to use |>. When the function is unary, it works just as well.

Let’s imagine a scenario where Promise.Js.fromBsPromise takes two argument and the promise is the second argument. That would point me to using |> instead of -> to use that function. Then after that, what would I do to be able to use -> to leverage Proimse.Js.map after that?

You can use _ to place where the left side of the pipe goes with ->, and it is desugared (see the compiled JS. I think it is less expensive than pipe. (they are pretty much the same?)

let dummy =
  Js.Promise.resolve(4)
  ->Js.Promise.then_(n => Js.Promise.resolve(n + 1), _)
  ->Js.Promise.then_(n => Js.Promise.resolve(n + 1), _)

Playground link

1 Like

Thanks! That’ll work!

They are not exactly the same.The → operator is completely desugared on the syntax level, the |> is a normal infix operator function call that happens to get optimized by the compiler later on (that’s why you won’t notice any difference in the JS output).

2 Likes