prosseek
prosseek

Reputation: 190679

Scala's equivalence to |> in F# or ->> in Clojure

In Scala, when I have this expression

f1 ( f2 ( f3 (p))) 

Is there a way that I can use something like in

F#

p |> f3 |> f2 |> f1 

or Clojure?

(->> p f3 f2 f1)

Upvotes: 4

Views: 897

Answers (2)

Luigi Plinge
Luigi Plinge

Reputation: 51109

If you want to write it yourself without using external libraries,

implicit class Pipe[T](x: T) {
  def |> [U](f: T=>U): U = f(x)
}

So, this implicit class pattern is used for extension methods. It's shorthand for the "pimp my library" pattern:

class Pipe[T](x: T) { /*extension methods here*/ }
implicit def anyToPipe[T](x: T) = new Pipe(x)

As with any implicit conversion, if the method name is not valid for T, but there is a function T => Pipe in implicit scope, and the method is valid on Pipe, the function (or method here - effectively the same thing) is inserted by the compiler so you get a Pipe instance.

def |> [U](f: T=>U): U = f(x)

This is just a method called |> that has a parameter f of type T=>U, i.e. a Function1[T,U], where T is the input type and U is the result type. Because we want this to work for any type, we need to make the method type-parameterized on U by adding [U]. (If we used T=>Any instead, our return would be of type Any, which wouldn't be much use.) The return value is just the application of the function to the original value, as required.

Upvotes: 5

dcastro
dcastro

Reputation: 68640

There is no equivalent to F#'s pipe operator in Scala...

... but there is one in the scalaz library. And it's also named |>. They nicknamed it the "thrush operator".

import scalaz._
import Scalaz._

def f(s: String) = s.length

"hi" |> f

Here's the scaladoc.

Upvotes: 6

Related Questions