Вызов функции F # более высокого порядка из C # - PullRequest
19 голосов
/ 23 декабря 2009

Учитывая функцию высшего порядка F # (принимая функцию в параметре):

let ApplyOn2 (f:int->int) = f(2)  

и функция C #

public static int Increment(int a) { return a++; } 

Как мне вызвать ApplyOn2 с Increment в качестве параметра (из C #)? Обратите внимание, что ApplyOn2 экспортируется как Microsoft.FSharp.Core.FSharpFunc<int,int>, что не соответствует подписи Increment.

Ответы [ 3 ]

29 голосов
/ 23 декабря 2009

Чтобы получить FSharpFunc из эквивалентной функции C #, используйте:

Func<int,int> cs_func = (i) => ++i;
var fsharp_func = Microsoft.FSharp.Core.FSharpFunc<int,int>.FromConverter(
    new Converter<int,int>(cs_func));

Чтобы получить функцию C # из эквивалентного FSharpFunc, используйте

var cs_func = Microsoft.FSharp.Core.FSharpFunc<int,int>.ToConverter(fsharp_func);
int i = cs_func(2);

Итак, в данном конкретном случае ваш код может выглядеть следующим образом:

Func<int, int> cs_func = (int i) => ++i;
int result = ApplyOn22(Microsoft.FSharp.Core.FSharpFunc<int, int>.FromConverter(
            new Converter<int, int>(cs_func)));
17 голосов
/ 23 декабря 2009

Если вы хотите обеспечить более дружественный интерфейс взаимодействия, рассмотрите возможность использования типа делегата System.Func непосредственно в F #:

let ApplyOn2 (f : System.Func<int, int>) = f.Invoke(2)

Вы сможете очень легко вызывать свою функцию F # в C #, например:

MyFSharpModule.ApplyOn2(Increment); // 3

Однако существует проблема с функцией увеличения, как вы ее написали. Вам нужна префиксная форма оператора приращения, чтобы ваша функция возвращала правильный результат:

public static int Increment(int a) { return ++a; }
0 голосов
/ 23 декабря 2009

Просто создайте ссылку на вашу сборку:

#r @"Path\To\Your\Library.dll"
let ApplyOn2 (f:int->int) = f(2)
ApplyOn2 Library.Class.Increment
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...