Scala 等价于 F# 中的 |> 或 Clojure 中的 ->>

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

在 Scala 中,当我有这个表达式时

f1 ( f2 ( f3 (p))) 

有什么方法可以让我使用类似

的东西

F#

p |> f3 |> f2 |> f1 

还是 Clojure?

(->> p f3 f2 f1)

Scala 中没有与 F# 的管道运算符等效的...

...但是 scalaz library 中有一个。它也被命名为|>。他们给它起了个绰号 "thrush operator".

import scalaz._
import Scalaz._

def f(s: String) = s.length

"hi" |> f

这是scaladoc

如果你想自己写,不使用外部库,

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

因此,此 implicit class 模式用于扩展方法。 "pimp my library" 模式是 shorthand:

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

与任何隐式转换一样,如果方法名称对 T 无效,但在隐式范围内有一个函数 T => Pipe,并且该方法对 Pipe 有效,函数(或此处的方法 - 实际上是同一件事)由编译器插入,因此您得到一个 Pipe 实例。

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

这只是一个名为 |> 的方法,它具有 T=>U 类型的参数 f,即 Function1[T,U],其中 T 是输入type 和 U 是结果类型。因为我们希望它适用于任何类型,所以我们需要通过添加 [U] 使方法在 U 上进行类型参数化。 (如果我们使用 T=>Any 代替,我们的 return 将是 Any 类型,这不会有太大用处。) return 值只是函数的应用根据需要恢复为原始值。