静态方法是否更具可组合性?

COO*_*ANS 6 lambda static functional-programming scala

我有一个名为Cell的案例类,它有无参数的方法,可以向上,向下,向左,向右移动单元格......

 case class Cell(topLeft: Coordinate, botRight: Coordinate) {

  def up: Cell = {
    Cell(
      Coordinate(topLeft.x + 0, topLeft.y - 1)
      , Coordinate(botRight.x + 0, botRight.y - 1))
  }
}
Run Code Online (Sandbox Code Playgroud)

这种向上操作应该是一个实例方法,并且这样调用是正确的:

val cell = Cell(x,y)
cell.up
Run Code Online (Sandbox Code Playgroud)

但是,如果我使这些操作属于一个伴随对象的静态函数,就像这样,

object Cell{

  def up(cell: Cell): Cell = {
    Cell(
      Coordinate(cell.topLeft.x + 0, cell.topLeft.y - 1)
      , Coordinate(cell.botRight.x + 0, cell.botRight.y - 1))
  }
...
}
Run Code Online (Sandbox Code Playgroud)

然后他们似乎更容易组合.现在我可以向上,向下,向左或向右传递,作为Cell => Cell类型的参数.作为无参数实例方法,它等价于一个值,因此不能作为函数传递.

请参阅下面的两条注释行.

    private def move(move: Cell => Cell, team: Team, nucleus: Coordinate): Team = {

    val (mover, others) = team.cells.partition(_.nucleus == Some(nucleus))

    val newCell = move(mover.head)  // Works using STATIC move

    val newCell = mover.head.move  // Doesn't Work (needs .up, .down etc...)

    if(mover.nonEmpty){
      if(isValidCellState(newCell)) {
        Team(newCell :: others)
      }else{
        throw new BadMoveException("Invalid move from this position")
      }
    }else{
      throw new BadMoveException("You didn't select a cell to move")
    }
  }
Run Code Online (Sandbox Code Playgroud)

如果我想要两个功能:

  1. 能够像实例方法一样调用函数
  2. 将这些功能用作其他功能的参数

看来我需要在伴随对象中静态定义方法,然后通过引用静态实现在类中定义它们

def up = Cell.up(this)
Run Code Online (Sandbox Code Playgroud)

这是不好的做法,看起来有点臭.

Bri*_*hon 7

Scala使得为这样的情况创建lambdas变得非常容易:

move(_.up, team, nucleus)
Run Code Online (Sandbox Code Playgroud)

你会发现这甚至比它短Cell.up.出于这个原因,似乎没有必要在伴侣中定义它们.