我试图通过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))
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
直接调用update(2)(1)(1)
有效,因此转换为更新方法无法正常运行。我的错误在哪里?
答案 0 :(得分:7)
将赋值语法移植到update
的调用中,将赋值的LHS上的单个参数列表的串联与赋值的RHS上的值映射到{{1}的第一个参数块无论update
方法定义有多少其他参数块,方法定义。虽然这种转换在某种意义上将单个参数块拆分为两个(一个在LHS上,一个在分配的RHS上),但它不会以你想要的方式进一步拆分左参数块。
我还认为你对你所展示的update
显式调用的例子有误。这不会使用您给出的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)
^
更新desbraring 适用于此定义,但可能不符合您的预期:如上所述,它仅适用于第一个参数列表,导致像
这样的结构scala> class Matrix { def update(i: Int)(j: Int)(value: Int) = (i, j, value) }
defined class Matrix
这里,初始的一位参数块被分割为赋值的LHS上的空参数块(即scala> val m = new Matrix
m: Matrix = Matrix@39741f43
scala> (m() = 1)(2)(3)
res0: (Int, Int, Int) = (1,2,3)
)和RHS上的一个参数块(即{{1 }})。然后是原始定义中的其余参数块。
如果您对此行为感到惊讶,请won't be the first。
您所遵循的语法可以通过稍微不同的路径实现,
()
答案 1 :(得分:0)
我的猜测是,它根本不受支持。可能不是由于明确的设计决定,因为我不明白为什么它原则上不应该工作。
与apply
有关的翻译,即将m(i)(j)
转换为m.apply(i, j)
时执行的翻译,似乎能够应对干扰。在您的程序上运行scala -print
以查看翻译产生的代码。
另一方面,与update
有关的翻译似乎无法应对干扰。由于错误消息为missing arguments for method apply
,因此它看起来好像是currying使翻译人员感到困惑,因此它试图将m(i)(j) = v
翻译成m.apply
,但随后会搞砸所需参数的数量。遗憾的是,scala -print
在这里没有帮助,因为类型检查器会过早终止翻译。
以下是语言规范(Scala 2.9,&#34; 6.15作业&#34;)所说的作业。由于没有提到currying,我认为它没有明确支持。我无法找到apply
的相应段落,但我想在那里干练是完全巧合的。
赋值 f(args)= e ,左侧有一个函数应用程序 '='运算符被解释为 f.update(args,e),即 调用由 f 定义的更新函数。