Использование делегатов C# с функциями F#

Я пытаюсь вызвать функцию aC# из F#, где функция C# принимает функцию (делегат?) В качестве параметра, и мне нужно, чтобы этот аргумент был функцией aF#. Например:

Образец с #

public static void function_1(double x, ref double y)
{
    y = Math.Exp(x);
}

main()
{ 
    state s;
    call_func(s, function_1)
}

Так, call_func имеет параметр типа void fn(double, ref double)

В ф # я попробовал:

let function_1 (x:double) (y:double byref) = 
    let y = 6.0
    ()

let test = 
    let s = new state
    let ret = call_func(s, function_1)

Но я получаю ошибку, что F# function_1 имеет тип double -> double byref -> unit когда это должен быть тип делегата void fn(double, ref double),

Могу ли я привести тип или что-то в этом роде? Или есть ошибка?

1 ответ

Решение

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

let function_1 (x:double) (y:double) = 
    ()

Program.call_func(s, new Action<double, double>(function_1))

Но по какой-то причине, если попытаться использовать тот же подход с делегатом, который содержит ref, вы получите эту ошибку:

Это значение функции используется для создания типа делегата, чья сигнатура включает аргумент byref. Вы должны использовать явное лямбда-выражение, принимающее 2 аргумента.

Итак, если вы будете следовать советам, данным в сообщении об ошибке, вы можете написать следующее:

let function_1 (x:double) (y:double byref) = 
    y <- 6.0

Program.call_func(s, new fn(fun x -> fun y -> function_1 x &y))

Это компилируется и работает как положено.

Обратите внимание, что для изменения параметра y, вы должны использовать <- оператор. С помощью let y = 6.0 объявляет совершенно другую переменную, которая скрывает параметр.

Другие вопросы по тегам