问题
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)
回答1:
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.
回答2:
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.
来源:https://stackoverflow.com/questions/32506410/scalas-equivalence-to-in-f-or-in-clojure