在scala中链接函数调用(或相当于Ruby的yield_self)


链接

函数调用的惯用方法是什么,在每个函数调用之间传递结果,并在 Scala 中提供参数?

下面是一个示例:

def a(x : A, param : String) : A = x
def b(x : A, param : String) : A = x
def c(x : A, param : String) : A = x
def d(x : A, param : String, anotherParam : String) : A = x
val start = A()
d(c(b(a(start, "par1"), "par2"), "par3"), "par4", "anotherPar")

我想到的一种方法是Ruby的Kernel#yield_self它允许执行以下操作:

start
  .yield_self {|x| a(x, "par1") }
  .yield_self {|x| b(x, "par2") } 
  .yield_self {|x| c(x, "par3") } 
  .yield_self {|x| d(x, "par4", "anotherPar) } 

您可以将函数链组合成一个函数:

val start = new A()
val func: (A => A) =
  ((x: A) => a(x, "par1"))
    .andThen(b(_, "par2"))
    .andThen(c(_, "par3"))
    .andThen(d(_, "par4", "anotherPar"))
func(start)

但我不确定这是否是你的目标。

我会说链接函数使用得很好...链接已经不是那么糟糕了:

(
  { (x: A) => a(x, "par1") } andThen 
  { x => b(x, "par2") } andThen 
  { x => c(x, "par3") } andThen 
  { x => d(x, "par4", "anotherPar") }
)(start)

但是,如果您坚持使用yieldSelf方法,请在此处:

import scala.language.implicitConversions
case class YieldSelf[X](x: X) {
  def yieldSelf[Y](f: X => Y): Y = f(x)
}
implicit def everythingCanYieldSelf[X](x: X) = YieldSelf(x)
start.
  yieldSelf{ a(_, "par1") }.
  yieldSelf{ b(_, "par2") }.
  yieldSelf{ c(_, "par3") }.
  yieldSelf{ d(_, "par4", "anotherPar") }

一旦隐式定义在作用域中,它就会为每个对象添加一个yieldSelf方法,该方法具有与 Ruby 中相同的语义。

最新更新