2015-02-10 55 views
0

下面的代碼使用lambda函數:與委託和回調funcitons問題 - fsharp,交易所託管API

// https://msdn.microsoft.com/en-us/library/office/dn567668.aspx#Create 
#r "C:\Program Files\Microsoft\Exchange\Web Services\2.2\Microsoft.Exchange.WebServices.dll" 

open Microsoft.Exchange.WebServices.Data 
open System 

let exchangeService emailAddress password = 
    let service = new ExchangeService(ExchangeVersion.Exchange2010_SP2) 
    service.Credentials <- new WebCredentials(emailAddress,password) 
    service.AutodiscoverUrl(emailAddress, (fun (redirectionUrl:string) -> redirectionUrl.ToLower().StartsWith("https://"))) 
    service 

但我有問題,當我綁定在AutodiscoverUrl使用的名稱在lambda:

let x (redirectionUrl:string) = redirectionUrl.ToLower().StartsWith("https://") 
service.AutodiscoverUrl(emailAddress, x) 

Visual Studio抱怨「x」。

「這表達預計將有類型Microsoft.Exchange.WebServices.Autodiscover.AutodiscoverRedirectionUrlValidationCallback但這裏有類型的字符串 - > BOOL」

請注意,這是相同的簽名上面的lambda函數。使用F#交互檢查...

fun (redirectionUrl:string) -> redirectionUrl.ToLower().StartsWith("https://") 
val it : redirectionUrl:string -> bool = <fun:[email protected]> 

let x (redirectionUrl:string) = redirectionUrl.ToLower().StartsWith("https://") 
val x : redirectionUrl:string -> bool 

我缺少什麼?

回答

1

當調用一個將委託作爲參數的方法時,F#允許您使用lambda函數調用它並自動將其轉換爲委託(這就是您的第一個版本工作的原因)。

我認爲並非所有F#版本都會自動將命名函數轉換爲委託,所以當您想使用命名函數作爲參數時,可以通過顯式創建委託來實現。這意味着,如果你想通過函數x作爲參數,你可以這樣寫:

service.AutodiscoverUrl(emailAddress, AutodiscoverRedirectionUrlValidationCallback (x)) 

在這種情況下,它可能是更短的包裹它在短期內聯lambda函數:

service.AutodiscoverUrl(emailAddress, fun arg -> x arg) 

編輯:在最新版本的F#中,從命名函數到委託的轉換也應該起作用 - 但我認爲這取決於這是什麼類型的委託,還有哪些其他重載以及您使用的是哪個F#版本。以上應該始終工作。

+0

感謝Tomas。 「轉換到代表」是有道理的 - 因此是錯誤信息。 – 2015-02-10 18:21:10