2013-09-24 89 views
1

SICP 1.3.2,還有這個功能爲什麼Scala中的匿名函數和函數是這樣構造的?

(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代碼相比,這看起來完全是「外來的」。

回答

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,Scala有許多更易訪問的結構來編寫出色的代碼。

+0

請參閱上面的編輯 – dotnetN00b

+0

關於爲什麼上面顯示的代碼是以這種方式編寫的,它在我看來就像是Clojure的一個大部分直接翻譯或一些其他類似lisp的語言,由更熟悉前者比後者。它從使用該語言的移民看到Java(有時令人震驚)的Scala代碼做出了有趣的改變!我希望在有經驗的情況下,以及專家對Scala的接觸以及諸如此處發現的答案,這些Scala移民將學習如我在這裏嘗試的那樣產生更清晰更自然的翻譯。 – Shadowlands

+0

所以我顯然不清楚。我想我想問的是:這是什麼構造?通常情況下,表達式或表達式用括號括起來。但是我所看到的只是一個匿名函數,它的身體用圓括號包裹,然後緊接着在括號中包含f_lambda2的身體。所以我只是不瞭解這個建築,以及它是如何融合在一起的。 – dotnetN00b

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」:

(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足夠靈活,可以讓你表達同樣的東西,從而可以使用很多不同的風格。

+0

請參閱上面的編輯 – dotnetN00b

+0

已更新,希望對此有所幫助。 – chrisloy

相關問題