Curried更新方法

dam*_*uar 2 scala

我正在尝试curried应用和更新这样的方法:

def apply(i: Int)(j: Int) = matrix(i)(j)
def update(i: Int, j: Int, value: Int) = 
  new Matrix(n, m, (x, y) => if ((i,j) == (x,y)) value else matrix(x)(y))
Run Code Online (Sandbox Code Playgroud)

Apply方法正常工作,但更新方法抱怨:

scala> matrix(2)(1) = 1
<console>:16: error: missing arguments for method apply in class Matrix;
follow this method with `_' if you want to treat it as a partially applied function
              matrix(2)(1) = 1
Run Code Online (Sandbox Code Playgroud)

调用直接update(2)(1)(1)工作,因此它是一种无法正常工作的转换更新方法.我的错误在哪里?

Mil*_*bin 7

赋值语法的脱糖成的调用update映射与上分配到的第一个参数块的RHS值的分配的LHS单个参数列表的级联update而不管有多少其他参数块的方法的定义,update方法定义有.虽然这种转换在某种意义上将单个参数块拆分为两个(一个在LHS上,一个在分配的RHS上),但它不会以你想要的方式进一步拆分左参数块.

我也认为你误解了update你所展示的显式调用的例子.这不会编译update您给出的定义,

scala> class Matrix { def update(i: Int, j: Int, value: Int) = (i, j, value) }
defined class Matrix

scala> val m = new Matrix
m: Matrix = Matrix@37176bc4

scala> m.update(1)(2)(3)
<console>:10: error: not enough arguments for method update: (i: Int, j: Int, value: Int)(Int, Int, Int).
Unspecified value parameters j, value.
              m.update(1)(2)(3)
                      ^
Run Code Online (Sandbox Code Playgroud)

我怀疑你在实验过程中实际定义了更新,

scala> class Matrix { def update(i: Int)(j: Int)(value: Int) = (i, j, value) }
defined class Matrix
Run Code Online (Sandbox Code Playgroud)

更新desugaring 确实适用于此定义,但可能不是您期望的方式:如上所述,它仅适用于第一个参数列表,这导致构造,如,

scala> val m = new Matrix
m: Matrix = Matrix@39741f43

scala> (m() = 1)(2)(3)
res0: (Int, Int, Int) = (1,2,3)
Run Code Online (Sandbox Code Playgroud)

这里,初始的一位参数块被分成分配的LHS上的空参数块(即,())和RHS上的一个参数块(即,1).然后是原始定义中的其余参数块.

如果你对这种行为感到惊讶,你将不会是第一个.

你所遵循的语法可以通过稍微不同的路线实现,

scala> class Matrix {
     |   class MatrixAux(i : Int) {
     |     def apply(j : Int) = 23
     |     def update(j: Int, value: Int) = (i, j, value)
     |   }
     | 
     |   def apply(i: Int) = new MatrixAux(i)
     | }
defined class Matrix

scala> val m = new Matrix
m: Matrix = Matrix@3af30087

scala> m(1)(2)      // invokes MatrixAux.apply
res0: Int = 23

scala> m(1)(2) = 3  // invokes MatrixAux.update
res1: (Int, Int, Int) = (1,2,3)
Run Code Online (Sandbox Code Playgroud)