【问题标题】:Chaining function calls in scala (or equivalent of Ruby's yield_self)在 Scala 中链接函数调用(或等效于 Ruby 的 yield_self)
【发布时间】:2018-02-02 15:22:45
【问题描述】:

什么是链接函数调用的惯用方式,在每个函数调用之间传递结果,并在 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) } 

【问题讨论】:

    标签: scala


    【解决方案1】:

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

    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)
    

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

    【讨论】:

    • 错过了andThen,这绝对可以。谢谢!
    【解决方案2】:

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

    (
      { (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 中的相同。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-01-08
      • 2020-09-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-01-21
      相关资源
      最近更新 更多