使用 Case Class 方法的高阶函数

Higher Order Function with Case Class Method

我正在尝试删除代码中的冗余。我想我可以用高阶函数来做。

我想做的是将f3的公共位分解出来,然后将f1和f2不同的位作为参数传递给f3。

object Example extends App {

  case class action(name: String, age: Int) {
    def setName(new_name: String): action = this.copy(name = new_name)
    def setAge(new_age: Int): action = this.copy(age = new_age)
  }

  def f1(x: action, increment: Int) = {
    // big block of code which does a....

    // a single line in the block calling
    val older_person = x setAge (x.age + increment)

    // big block of code which does b....
  }

  def f2(x: action, new_name: String) = {
    // big block of code which does a....

    // a single line in the block calling
    val new_name_person = x setName new_name

    // big block of code which does b....
  }

  /* Now as there is clearly a redundancy, which can be solved by higher order functions.
    I want to combine f1 and f2 into a single function. The function will take in the action, the value, and the 
    function to apply. It will then call the relevant function inside the method.
   */
  def f3[T](x: action)(f: T => action)(value: T) = {
   // big block of code which does a....
   // call x.f(value)
    val new_action = ??? 
   // big block of code which does b....
  }

  // then in my code I can call like this:
  // f3(x)(setAge)(100)
  // f3(x)(setName("new_name")
}

让我感到困惑的是,我如何传入一个函数,该函数是 case class 中的一个方法?无论如何,有没有一种优雅的方式来做到这一点?

f3 中,您可以简单地接受类型为 Action => Action 的函数(我将使用 Action 而不是 action 以减少混淆) .

def f3(x: Action)(copy: Action => Action) = {
  // big block of code which does a....

  // a single line in the block calling
  val new_name_person = copy(x)

  // big block of code which does b....
}

然后您可以定义一些有用的函数并使用柯里化使它们以后更易于使用:

object Action {
  def setName(name: String)(action: Action) = action.copy(name=name)
  def incAge(inc: Int)(action: Action) = action.copy(age=action.age+inc)
}

然后像这样使用它:

val x = Action("Foo", 42)
f3(x)(Action.incAge(100))
f3(x)(Action.setName("new_name"))

Try it in Scastie