2010-05-06 94 views
6

爲什麼...創建委託和Lambda表達式在F#

type IntDelegate = delegate of int -> unit 

type ListHelper = 
    static member ApplyDelegate (l : int list) (d : IntDelegate) = 
     l |> List.iter (fun x -> d.Invoke x) 

ListHelper.ApplyDelegate [1..10] (fun x -> printfn "%d" x) 

不能編譯,當:

type IntDelegate = delegate of int -> unit 

type ListHelper = 
    static member ApplyDelegate (l : int list, d : IntDelegate) = 
     l |> List.iter (fun x -> d.Invoke x) 

ListHelper.ApplyDelegate ([1..10], (fun x -> printfn "%d" x)) 

呢?

唯一的區別是在第二個ApplyDelegate將其參數作爲元組。

這個函數的參數太多,或者在沒有預期的功能

回答

11

我沒有看過的規範,以確認上下文中使用,但我猜測的隱式轉換從「lambda」到「named委託類型」僅出現在「成員調用」中。

您可以隨時進行轉換明確:

ListHelper.ApplyDelegate [1..10] (IntDelegate(fun x -> printfn "%d" x)) 

(錯誤診斷是相當差的,我將文件中的錯誤。)

編輯:

對於書呆子.. 。

呀,spec

8.13.6成員調用時的類型定向轉換如方法應用程序解析(請參閱 第14.4節)中所述,兩種類型定向轉換 應用於方法調用。

如果一個形式參數是委託 型DelegateType的,和實際 說法是語法功能 值(樂趣...),則該參數 解釋爲,如果它被寫 新DelegateType(樂趣...)。

只有在「成員調用」時,lambda纔會自動轉換爲委託類型。在curried成員的情況下,傳遞的第一個參數是一個成員調用,但是然後返回一個函數值來應用第二個參數,而函數調用沒有這個隱式轉換規則。

+0

謝謝。 「成員調用」到底是什麼以及爲什麼有元組參數會有所作爲? 成員應該總是採用tupled參數嗎? – 2010-05-06 18:52:48

+3

「成員」是你用'member'關鍵字定義的東西,例如,某些類型的靜態或實例方法。這些與通過'let f x = ...'或'fun'定義的「函數」形成對比,這些函數相對而言非常嚴格(例如,您不能重載函數,但可以重載成員)。成員們應該總是採取tupled的論據,是的;與特定於F#的函數相比,成員更多的是.NET-y實體。 – Brian 2010-05-06 18:59:57

+3

'tupled arguments'有所不同,因爲當它被元組化時,所有的參數都立刻被傳遞給成員,所以第二個參數是成員的一個參數。在curried參數的情況下,第一個參數是成員的一個參數,並且導致一個新的(非成員)函數值,然後接受第二個參數。 – Brian 2010-05-06 19:03:40