7

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?

1 Answer 1

10

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.

Sign up to request clarification or add additional context in comments.

4 Comments

thanks for your help, but I'm getting an error "The type 'fn' is not defined" for the new argument.
fn is the type of the delegate that the function expects. Maybe you're missing open for the namerspace it's in. Or it may be called something else in your code. Or it may be nested in some class (if that's the case, you should provide the name along with the name of type that contains the delegate).
OK, I understand - that compiles now. If I leave out the new and the fn it compiles also, would that work?
@b1g3ar5 - Yes, the compiler will implicitly call the delegate constructor when a lambda is passed to a method where a delegate is expected.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.