1

SICP 1.3.2中,有这个功能

(define (f x y)
  ((lambda (a b)
     (+ (* x (square a))
        (* y b)
        (* a b)))
   (+ 1 (* x y))
   (- 1 y)))

现在在追错30分钟后,我找到了这个页面,它提供了这个功能

  def f_lambda(x: Int, y: Int) =
    (((a: Int, b: Int) => ((x * square(a)) + (y * b) + (a * b)))
      (1 + (x * y), 1 - y)) 

我不明白为什么它被括号包围(如堡垒)。

编辑:对不起,我真正的问题是我不明白为什么这个函数是这样构造的。换句话说,为什么首先需要所有括号。与我目前看到的 Scala 代码相比,这看起来完全“陌生”。

4

2 回答 2

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)
}

总体而言,仅仅因为编码概念的最有效、最紧凑的表示可能涉及括号疯狂(耶,Lisp!),这并不意味着必须将其转移到 Scala,它具有许多更易于编写表达性的构造代码。

于 2013-09-24T09:55:31.653 回答
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 足够灵活,可以使用多种不同的风格来表达相同的东西。

于 2013-09-24T09:55:46.653 回答