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

pro*_*eek 3 f# scala clojure operator-keyword

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

f1 ( f2 ( f3 (p))) 
Run Code Online (Sandbox Code Playgroud)

有没有办法让我可以使用像

F#

p |> f3 |> f2 |> f1 
Run Code Online (Sandbox Code Playgroud)

还是Clojure?

(->> p f3 f2 f1)
Run Code Online (Sandbox Code Playgroud)

dca*_*tro 6

在Scala中没有与F#的管道运营商相当的东西......

...但是scalaz库中有一个.它也被命名了|>.他们昵称它为"鹅口疮运营商".

import scalaz._
import Scalaz._

def f(s: String) = s.length

"hi" |> f
Run Code Online (Sandbox Code Playgroud)

这是scaladoc.


Lui*_*hys 5

如果你想在不使用外部库的情况下自己编写,

implicit class Pipe[T](x: T) {
  def |> [U](f: T=>U): U = f(x)
}
Run Code Online (Sandbox Code Playgroud)

因此,此implicit class模式用于扩展方法.它是"皮条客我的图书馆"模式的简写:

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

与任何隐式转换一样,如果方法名称无效T,但T => Pipe隐式作用域中有一个函数,并且该方法有效Pipe,则编译器会插入函数(或此处的方法 - 实际上是相同的东西),因此您得到一个Pipe实例.

def |> [U](f: T=>U): U = f(x)
Run Code Online (Sandbox Code Playgroud)

这只是一个名为|>参数f类型的方法T=>U,即a Function1[T,U],其中T是输入类型,U是结果类型.因为我们希望这适用于任何类型,我们需要对方法进行类型参数化U通过添加[U].(如果我们使用了T=>Any,我们的返回将是类型Any,这将没有多大用处.)返回值只是将函数应用于原始值,如果需要.