我正在努力understand the behavior of type inference。例如,这无法编译:
import math._
object Distance {
def euclidean (p: Seq[Double], c: Seq[Double]) = {
val d = (p,c)
.zipped map (_ - _)
.map pow(_,2.0)
.foldLeft(0.0)(_+_)
sqrt(d)
}
}
使用:
错误:(5,17)缺少扩展函数的参数类型((x $ 3)=> scala.Tuple2(p,c).zipped.map(((x $ 1,x $ 2)=> x $ 1. $ minus(x $ 2)))。map.pow(scala.Tuple2(x $ 3,2.0).foldLeft(0.0)((x $ 4, x $ 5)=> X $ 4 $加(X $ 5))))) .map pow(_,2.0)
I somehow do not get how the de-sugaring works我最终不得不围绕类型声明和括号或摆脱infix notations以支持显式方法调用(使用.
)。
例如,这个有效:
import math._
object Distance {
def euclidean (p: Seq[Double], c: Seq[Double]) = {
val d = (p,c)
.zipped.map (_ - _)
.map ( (x:Double) => pow(x,2.0) )
.foldLeft(0.0)(_+_)
sqrt(d)
}
}
但没有机会拥有一个可爱的oneliner:
(p,c).zipped map pow(_ - _, 2.0)
我有兴趣了解rules of the game的 for dummies explain 。
答案 0 :(得分:3)
问题似乎是中缀符号。规则实际上非常简单:采用一个参数的方法可以用中缀表示法编写。这样您就可以写a b c
而不是a.b(c)
。
1+2*3
是1.+(2.*(3))
而不是(1.+(2)).*(3)
。您已链接的规范的运算符部分的优先级(简称为)由运算符的前导符号控制。
要注意的另一个重要细节是以:
结尾的运算符绑定右侧的参数。因此a :: b
相当于b.::(a)
。
另一个棘手的问题是圆括号。在点符号中,它们只是包装参数列表。在运算符表示法中,他们可能需要自己包装参数(例如函数文字)。
顺便说一下:您的单行内容可以这样写:(p,c).zipped map {(a, b) => pow(a - b, 2.0)}
请注意,我已使用{}
包装了函数文字,这只是为了提高可读性,()
也可以。