Dot-Net

在 F# 中使用 Lambda 表達式創建委託

  • August 31, 2014

為什麼…

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將其參數作為一個元組。

此函式接受太多參數,或在不期望函式的上下文中使用

我沒有查看規範來確認,但我猜測從“lambda”到“命名委託類型”的隱式轉換只發生在“成員呼叫”中。

您始終可以使轉換顯式:

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

(錯誤診斷很差;我會送出一個錯誤。)

編輯:

對於笨蛋…

是的,規範

8.13.6 成員呼叫中的類型導向轉換 如方法應用解決方案(參見第 14.4 節)中所述,在方法呼叫中應用了兩種類型導向的轉換。

如果形式參數是委託類型 DelegateType,而實際參數在語法上是函式值 (fun …),則該參數被解釋為好像它已被編寫為 new DelegateType(fun …)。

lambda 僅在“成員呼叫”時自動轉換為委託類型。在 curried 成員的情況下,傳遞的第一個參數是成員呼叫,但隨後返回一個函式值以應用第二個參數,並且函式呼叫沒有此隱式轉換規則。

引用自:https://stackoverflow.com/questions/2783450