在SICP 1.3.2中,有这个功能
(define (f x y)
((lambda (a b)
(+ (* x (square a))
(* y b)
(* a b)))
(+ 1 (* x y))
(- 1 y)))
现在在追踪错误30分钟后,我发现this page并提供了此功能
def f_lambda(x: Int, y: Int) =
(((a: Int, b: Int) => ((x * square(a)) + (y * b) + (a * b)))
(1 + (x * y), 1 - y))
我不明白为什么它被括号包围(就像一个堡垒)。
编辑:对不起,我的真正问题是我不明白为什么这个功能是按原样构建的。换句话说,为什么首先需要所有括号。与我迄今为止看到的Scala代码相比,这看起来完全是“外来的”。
答案 0 :(得分:2)
首先,在上面给出的特定示例中,当然可以消除一些括号中的一对,但在最外层对的情况下,这确实需要将最后一行的部分或全部放在末尾。上一行:
def f_lambda2(x: Int, y: Int) =
((a: Int, b: Int) => (x * square(a) + y * b + a * b))(1 + x * y, 1 - y)
那就是说,你可以 - 像任何代码一样 - 选择加上额外的括号来澄清事物(例如,围绕乘法来使优先级更清晰)。
其次,还有其他方法可以编写这样一个功能,可以使任何读者都能清楚地看到它。这确实意味着代码的简洁性,但我认为获得的清晰度绝对值得:
def f_lambda3(x: Int, y: Int) = {
def inner(a: Int, b: Int) = (x * square(a)) + (y * b) + (a * b)
inner(1 + x * y, 1 - y)
}
总的来说,仅仅因为编码概念的最有效,最紧凑的表示可能涉及支架疯狂(yay,Lisp!),这并不意味着必须将其转移到Scala,Scala具有许多更易于访问的结构用于编写令人振奋的代码。
答案 1 :(得分:2)
我也不明白。你可以剥掉一些:
def f_lambda(x: Int, y: Int) =
((a: Int, b: Int) => (x * square(a)) + (y * b) + (a * b)) (1 + (x * y), 1 - y)
或者,如果您想依赖乘法优先于加法的事实:
def f_lambda(x: Int, y: Int) =
((a: Int, b: Int) => x * square(a) + y * b + a * b) (1 + x * y, 1 - y)
我个人认为第一个更具可读性。
编辑:
打破这一点,这是声明一个匿名函数,它将两个Int作为参数,样式为“a”和“b”:
(a: Int, b: Int) => x*square(a) + y*b + a*b
注意,这仍然使用x和y(作为外部方法的参数)。然后使用a = 1 + xy和b = 1-y来应用此内部函数。
所以代替,我相信你最终得到:
x*square(1 + x*y) + y*(1 - y) + (1 + x*y)*(1 -y)
为什么不首先以这种方式编写(或使用Shadowland的内部函数)?嗯,这是一个风格和背景的问题,我猜,所以我不能真正猜测作者的初衷。关键是Scala足够灵活,允许许多不同的风格,你可以用来表达同样的事情。