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)

とはいえ、他のコードと同様に、物事を明確にするために余分な括弧を入れることもできます (たとえば、優先順位を明確にするために乗算の周りに)。

第 2 に、このような関数を記述する別の方法があり、何が起こっているのかを読者にとってより明確にすることができます。これはコードの簡潔さを意味しますが、得られる明快さは間違いなく価値があると思います:

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)

個人的には前者の方が読みやすいと思います。

編集:

これを少し分解すると、これは "a" と "b" のスタイルの 2 つの Int を引数として取る無名関数を宣言しています。

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

そもそもこのように(またはシャドウランドのような内部関数を使用して)書いてみませんか?まあ、それはスタイルと文脈の問題だと思うので、作者の最初の意図を本当に推測することはできません. 重要なのは、Scala は柔軟性があり、同じことを表現するためにさまざまなスタイルを使用できるということです。

于 2013-09-24T09:55:46.653 に答える