Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Calling C# functions from F#

Tags:

c#

f#

I was trying to call this function from f#

http://msdn.microsoft.com/en-us/library/microsoft.windowsazure.cloudstorageaccount.setconfigurationsettingpublisher.aspx

The function signature is:

CloudStorageAccount.SetConfigurationSettingPublisher
      (Action<string, Func<string, bool>>) : unit

The C# call goes something like this:

CloudStorageAccount.SetConfigurationSettingPublisher((configName,
                                                  configSettingPublisher) =>
{
    string configValue = "something"
    configSettingPublisher(configValue);
});

whereas in F#, I had to do something like this:

let myPublisher configName (setter:Func<string, bool>) =
    let configValue = RoleEnvironment.GetConfigurationSettingValue(configName)
    setter.Invoke(configName) |> ignore

let act = new Action<string, Func<string, bool>>(myPublisher)

CloudStorageAccount.SetConfigurationSettingPublisher(act)

Can this be written more concisely in f#?

like image 422
Bala Avatar asked Dec 13 '22 11:12

Bala


1 Answers

F# automatically converts lambda functions created using the fun ... -> ... syntax to .NET delegate types such as Action. This means that you can use lambda function as an argument to SetConfigurationSettingPublisher directly like this:

CloudStorageAccount.SetConfigurationSettingPublisher(fun configName setter ->
    let configValue = RoleEnvironment.GetConfigurationSettingValue(configName)
    setter.Invoke(configName) |> ignore)

A function of multiple arguments can be converted to a delegate of multiple arguments (the arguments shouldn't be treated as a tuple). The type of setter is still Func<...> and not a simple F# function, so you need to call it using the Invoke method (but that shouldn't be a big deal).

If you want to turn setter from Func<string, bool> to an F# function string -> bool, you can define a simple active pattern:

let (|Func2|) (f:Func<_, _>) a = f.Invoke(a)

...and then you can write:

TestLib.A.SetConfigurationSettingPublisher(fun configName (Func2 setter) ->
    let configValue = "aa"
    setter(configName) |> ignore)
like image 130
Tomas Petricek Avatar answered Dec 24 '22 02:12

Tomas Petricek