寻找最佳实践以在Scala中动态组成函数

时间:2019-04-14 20:57:33

标签: scala

我正在尝试编写Scala代码以从客户端代码中获取功能列表,并使用链式方法对其进行组合,最后应用所组合的函数,我能够做到这一点。但是我感觉我没有这样做一种功能性的方式,因为我在Test.scala(下面)中用“ var”声明了一个函数变量,并在其之上继续编写函数。我相信应该有更好的方法,任何指导和建议都对我有帮助

Test.scala

case class Test(val int: Int){
  private final var function : Int => Int = (i: Int) => i
  def composeFunction( f: Int => Int)   : this.type = {
   function = function.andThen(f);
        this;
    }
  def applyFunction : Int = {
        function(int)
    }
}

客户代码:Main.scala

val c = new Test(6)
  .composeFunction((i: Int) => i *2)
  .composeFunction((i: Int) => i *4)
  .composeFunction((i: Int) => i *6)
  .applyFunction

4 个答案:

答案 0 :(得分:3)

val c = Some(6)
  .map((i: Int) => i *2)
  .map((i: Int) => i *4)
  .map((i: Int) => i *6)
  .get

如果需要惰性评估,请使用cats库

val lazyEval = Eval.later(6)
  .map((i: Int) => i *2)
  .map((i: Int) => i *4)
  .map((i: Int) => i *6)
  .value

答案 1 :(得分:2)

类似的功能组成可以通过重复应用andThen来实现,如下所示:

val c = ((i: Int) => i * 2) andThen ((i: Int) => i * 4) andThen ((i: Int) => i * 6)
c(6) // res0: Int = 288

答案 2 :(得分:1)

如果您想避免发生变异,最好的(仅?)方法是为您要变异的数据创建修改后的副本。
例如

final case class Test(int: Int, function: Int => Int = identity){
  def composeFunction(f: Int => Int): Test =
    this.copy(function = this.function.andThen(f))

  def applyFunction: Int =
    function(this.int)
}

val c = Test(6)
  .composeFunction(i => i * 2)
  .composeFunction(i => i * 4)
  .composeFunction(i => i * 6)
  .applyFunction // 288.

但是,说实话,这种设计对我来说似乎很奇怪。 也许,拥有一个函数列表,使用andThen将其简化,最后应用结果函数会更好吗?

答案 3 :(得分:0)

仅链接一个函数即可获得结果

case class Test(int: Int){
   def applyFunction(f: Int => Int): Test = {
   this.copy(f(int))
   }
}

// test
val c = Test(6)
.applyFunction((i: Int) => i * 2)
.applyFunction((i: Int) => i * 4)
.applyFunction((i: Int) => i * 6)
.int

println(c)

输出:

288