Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using c# delegates with f# functions

Tags:

f#

c#-to-f#

I am trying to call a c# function from f# where the c# function takes a function (delegate?) as a parameter and I need this argument to be a f# function. Eg:

Sample c#

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

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

So, call_func has a parameter of type void fn(double, ref double)

In f# I tried:

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)

But I get the error that the f# function_1 has type double -> double byref -> unit when it should be the type of the delegate void fn(double, ref double).

Can I cast the type or something like that? Or is there an error?

like image 832
b1g3ar5 Avatar asked Jan 31 '12 10:01

b1g3ar5


1 Answers

If you want to create a delegate from a function in F#, you can use the new operator and give it the function as an argument:

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

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

But, for some reason, if try to use the same approach with a delegate that contains ref, you get this error:

This function value is being used to construct a delegate type whose signature includes a byref argument. You must use an explicit lambda expression taking 2 arguments.

So, if you follow the advice given by the error message, you can write the following:

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))

This compiles, and works as expected.

Note that to modify the parameter y, you have to use the <- operator. Using let y = 6.0 declares completely different variable that shadows the parameter.

like image 106
svick Avatar answered Oct 29 '22 22:10

svick