Scala中使用点表示法的链接功能

时间:2019-02-21 20:41:00

标签: scala pipe-forward-operator

到目前为止,我所知道的在Scala中将函数链接在一起的唯一本地方法是使用andThen / compose。它可以完成工作,但看起来仍然很笨重。例如,如果我有3个函数应用于一个值(f1(f2(f3(value)))),则必须执行以下操作:

(f1 _ andThen f2 andThen f3)(value)

当链较长且函数需要多个参数时,问题甚至会更加严重。 F#使用'|>'运算符非常优雅地解决了这个难题,但是这种方法在Scala中效果不佳,因为该语言非常依赖点表示法,而currying是可选的。

问题是,是否可以在Scala中执行以下操作:

def addNumber(i: Int, s: String) = s + i
def doubleString(s: String) = (s + s, (s + s).length)
def trimString(i: (String, Int)) = i._1.substring(0, i._2-1)

addNumber(1,"Hello").doubleString.trimString

换句话说,只要函数具有不同的返回类型/参数,我们可以使用点符号将其链接起来。

2 个答案:

答案 0 :(得分:3)

您可能要等待几周的时间才能发布Scala 2.13(或使用pre-release 2.13-M5),它提供了pipe链接运算符:

import scala.util.chaining._

// def addNumber(i: Int, s: String) = s + i
// def doubleString(s: String) = (s + s, (s + s).length)
// def trimString(i: (String, Int)) = i._1.substring(0, i._2-1)
"Hello".pipe(addNumber(1, _)).pipe(doubleString).pipe(trimString)
// "Hello1Hello"

答案 1 :(得分:2)

您可以尝试使用Scalaz:

  import scalaz._
  import Scalaz._

  def addNumber(i: Int, s: String) = s + i
  def doubleString(s: String) = (s + s, (s + s).length)
  def trimString(i: (String, Int)) = i._1.substring(0, i._2-1)

  def main(args: Array[String]) : Unit  =
    println(addNumber(2, "44") |> doubleString |> trimString)