【问题标题】:Scala's equivalence to |> in F# or ->> in ClojureScala 与 F# 中的 |> 或 Clojure 中的 ->> 等价
【发布时间】:2015-09-10 15:49:27
【问题描述】:

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

f1 ( f2 ( f3 (p))) 

有没有办法可以使用类似 in

F#

p |> f3 |> f2 |> f1 

还是 Clojure?

(->> p f3 f2 f1)

【问题讨论】:

  • 只是一个注释:在 clojure 中写 (->> p f3 f2 f1) 就足够了,不需要额外的括号
  • @Shlomi:谢谢,更新了。

标签: scala clojure f# operator-keyword


【解决方案1】:

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

...但是scalaz library 中有一个。它也被命名为|>。他们给它起了个绰号“画眉操作员”。

import scalaz._
import Scalaz._

def f(s: String) = s.length

"hi" |> f

这是scaladoc

【讨论】:

    【解决方案2】:

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

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

    所以,这个implicit class 模式用于扩展方法。这是“pimp my library”模式的简写:

    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 是输入类型,U 是结果类型。因为我们希望它适用于任何类型,所以我们需要通过添加[U] 使方法在U 上进行类型参数化。 (如果我们使用T=>Any 代替,我们的返回类型将是Any,这不会有太大用处。)返回值只是函数对原始值的应用,根据需要。

    【讨论】:

      猜你喜欢
      • 2011-06-20
      • 1970-01-01
      • 2018-11-10
      • 2014-03-15
      • 2014-03-11
      • 2015-10-22
      • 2010-12-11
      • 2012-07-03
      • 1970-01-01
      相关资源
      最近更新 更多