Elixir includes a pipe operator |>
which it borrowed from F#. The way |>
works it that given a function on the left it takes the output of that function and applies it as the first argument of the following function.
1
2
3
4
def inc(x), do: x + 1
def double(x), do: x * 2
1 |> inc |> double
This can be simulated in Scala.
The first step is to identify the type signature. 1 |> inc
is saying any (A
) can call a method |>
and pass it a Function1[A, B]
.
1
2
3
implicit class PipeOp[A](a: A) {
def |>[B](f: Function1[A,B]): B = f(a)
}
That's it. No, really, that's it. That is the pipe operater implemented in Scala.
Partial Application
It might seem limiting that it's restricted to a Function1
. What if, for exmaple, the function we wanted to pipe was...
1
def incBy(incrementBy: Int, x: Int) = by + x
One thing we could do is partially apply the function.
1
1 |> incBy(5, _: Int)
For some reason this fails. It seems like it should work as a partially applied function returns a function. This might be a Scala compiler bug.
1
2
<console>:13: error: missing parameter type for expanded function ((x$1) => inc2(5, x$1))
incBy(5, _)
Currying
The work around, and probably the better choice in the first place, is to just curry the function to begin with.
1
2
3
4
5
def incBy(inc: Int)(x: Int) = inc + x
...
1 |> incBy(5)