2015-02-10 46 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