Return an FSharpFunc from F# to C# - f#

I want to write a function in F#, that exposes the following type signature to C#:
public static FSharpFunc<FSharpFunc<Unit,Unit>,Unit> foo(Action<Action> f)
In F# I tried writing:
let foo (f : Action<Action>) : ((unit -> unit) -> unit) = ...
But that produces the C# signature:
public static void foo(Action<Action> f, FSharpFunc<Unit,Unit> x)
The F# has treated my code equivalently to:
let foo (f : Action<Action>) (g : unit -> unit) : unit = ...
Of course, these are equivalent to F#, but very different in C#. Is there anything I can do to produce the C# I want? (F# 2.0.0.0)
As a quick hack, I rewrote my F# to:
let foo (f : Action<Action>) ((unit -> unit) -> unit)[] = ...
Then I just use Head in the C#.

If you write let foo x = fun () -> ... then the F# compiler optimizes the code and compiles it as a method that takes two arguments (instead of a method returning function which is what you need). To get a function value as the result, you need to "do something" before returning the function:
// Will be compiled as method taking Action, FastFunc and returning void
let foo1(x : Action<Action>) : (unit -> unit) -> unit =
fun f -> f ()
// Will be compiled as method taking Action and returning FastFunc of FastFunc
let foo2(x : Action<Action>) : ((unit -> unit) -> unit) =
ignore ();
fun f -> f ()
That said, exposing F# function type to C# in any way is a bad pattern and it shouldn't be done. When you have some F# API that is supposed to be used from C#, you should expose functions as delegates, so that C# consumers can use them naturally (without converting Action to F# function explicitly). It is generally easier to write the wrapping on the F# side.

Either:
Add a signature file, with val foo : Action<Action> -> ((unit -> unit) -> unit).
Use a static member of a nominal type, rather than a let-bound value in a module. That is, static member foo (x:Action<Action>) : ((unit -> unit) -> unit) = ...

something like this?
open System
let foo(x : Action<Action>) : (unit -> unit) -> unit = failwith "..."

Related

How to mimic F# compiler type checking?

In F#, I can write a function (fun x -> x * x) and confirm it has type int->int because the following code compiles:
let typeCheck<'T> (x:'T) = ()
typeCheck<int->int> (fun x -> x*x)
On the other hand, GetType for this function doesn't agree with typeof<int->int>:
> (fun x -> x*x).GetType() = typeof<int -> int>
val it : bool = false
If not GetType() and typeof, what functions can I call to mimic the type-checking done by the compiler?
The reason why GetType of a specific lambda function is not the same as typeof<int -> int> is that the F# compiler generates a new class for the function which inherits from int -> int. In other words, the types are not the same, but the type you get via GetType inherits from int -> int.
You can check for this easily using IsAssignableFrom. The following is true:
typeof<int -> int>.IsAssignableFrom((fun x -> x*x).GetType())
You can use the :? operator to check based on type. I boxed it because (int -> int) is a sealed type.
F# Why can't I use the :? operator in F# interactive?
> let f = box (fun x -> x*x);;
val f : obj
> f :? (int -> int);;
val it : bool = true
If you wanted to build your typecheck function you could use this. A 'T and a thing of type 'T, they would always have the same type so I made x an object here, and you can box it before looking at it. However you probably don't need to do this, so if you're new to F# you may be working harder than you need to.
let typeCheck<'T> (x: obj) =
x :? 'T
//which is the same as
x :? (int -> int)
//so you probably don't need to define your own :)

How do I assign a multi-parameter F# function to a C# variable?

I have the following F# function:
let myFSharpFunction : IO.TryTransform<IDatabaseService,EditForm,SyncType,ErrorDescription> =
fun _ _ -> Ok someValue
I would like to use this F# function as a value/delegate in my C# code:
FSharpFunc<IDatabaseService, FSharpFunc<EditForm, FSharpResult<SyncType, ErrorDescription>>> referenceToFSharpFunction = myFSharpFunction;
However, I get an error:
Error CS0428 Cannot convert method group 'myFSharpFunction' to
non-delegate type 'FSharpFunc>>'. Did you intend to invoke the
method?
I then tried:
public delegate FSharpResult<SyncType, ErrorDescription> myDelegate(IDatabaseService database, EditForm editForm);
...
myDelegate someDelegate = myFSharpFunction;
FSharpFunc<IDatabaseService, FSharpFunc<EditForm, FSharpResult<SyncType, ErrorDescription>>> FSharpFuncToInvoke = someDelegate;
However, this attempt also gave me an error:
type 'Sevan.Android.FormsSyncFragment.myDelegate' to
'Microsoft.FSharp.Core.FSharpFunc>>'
Update:
Attempt 1:
I then tried adding the following function to an F# module:
let toFunc2 f = Func<_, _, _> f // f : 'a -> 'b -> 'c
I next updated the C# code to the following:
var referenceToFSharpFunction = toFunc2<IDatabaseService, EditForm, FSharpResult<SyncType, ErrorDescription>>(myFSharpFunction);
But I then received this error:
Cannot convert method group 'FSharpFuncToInvoke' to non-delegate type
'FSharpFunc>>'. Did you intend to invoke
the method?
Attempt 2:
I also tried setting the F# code to the following:
let toFunc2 f = Func<IDatabaseService,EditForm, Result<SyncType,ErrorDescription>> f // f : 'a -> 'b -> 'c
Then within my C#, I attempted this:
var referenceToFSharpFunction = toFunc2<IDatabaseService, EditForm, FSharpResult<SyncType, ErrorDescription>>(myFSharpFunctione);
But that attempt gave me this error:
Error CS0308 The non-generic method
'Mock.toFunc2(FSharpFunc>>)' cannot be used with type arguments
In conclusion, how do I assign a multi-parameter F# function to a C# variable?
If you are defining some F# functionality that should be used by a C# client, then I would strongly recommend exposing all the functionality in a C#-friendly way - that means, doing all the wrapping on the F# side, so that the C# consumer does not have to worry about things like FSharpFunc at all.
It's a bit hard to say how this should work in your case - because your example does not actually show any realistic piece of code - only some kind of adapter with a fairly complex interface - but you could do something along the following lines:
// Your F# function that is used elsewhere in F# code
let myFsharpFunction =
fun _ _ -> Ok someValue
// Your F# logic, exposed as a C#-friendly `System.Func` delegate
let myCsharpFunction =
System.Func<_, _, _>(myFsharpFunction)
The F# function type FSharpFunc is something completely separate from the Func/Action used in C#, so you need to "convert" it by creating the respective type that C# understands, which is easy, but needs to be done for each number of arguments individually.
let toFunc1 f = Func<_, _> f // f : 'a -> 'b
let toFunc2 f = Func<_, _, _> f // f : 'a -> 'b -> 'c
// etc.
let toAction0 f = Action f // f : unit -> unit
let toAction1 f = Action<_> f // f : 'a -> unit
// etc.

Resolve operator conflicts on similar generic types

I'm using a third party library (Sauve.IO) which defines the standard bind operator >>= :
val inline (>>=) : first:('T -> Async<'U option>) -> second:('U -> Async<'V option>) -> input:'T -> Async<'V option>
I also have an internal library that would also like to define the operator over the type signature
Async<Response<'a>> -> ('a -> Async<Response<'b>>) -> Async<Response<'b>>
What is the cleanest way to use these two functions in the same namespace/module without running afoul of the restriction on overloading inline functions ?
How about renaming Suave's operator to some other infix operator?
let (>=>) = Suave.(>>=)
Judging from the signature, it looks like it is not bind anyway,
but actually Kleisli composition.
You may be able to leverage F#'s statically resolved ad-hoc polymorphism: hide the qualified operator invocation behind a separate, overloaded operator; then define yet another, inlined operator for actual use.
type Foo = Foo with
static member ($) (_ : Foo, first : _ -> Async<_ option>) =
fun second value -> Module1.(>>=) first second value
static member ($) (_ : Foo, arg1 : Async<Response<_>>) =
Module2.(>>=) arg1
let inline (>>=) arg1 arg2 = (Foo $ arg1) arg2
Do both operators have the same name (>>=) ?
If so I assume that Suave's operator came with it's own module or namespace?
In this case you can qualify their operator appending their module/namespace name like this Suave.(>>=) but in this case you have to call it as usual function. Here is simplified example:
module Suave =
let inline (>>=) a b = a + 2 * b
module Mine =
open Suave
let (>>=) a b = a - 3 * b
let r1 = Suave.(>>=) 1 3
let r2 = 1 >>= 3
Result:
val r1 : int = 7
val r2 : int = -8

F#: currying differences between functions and static members

Can please someone explain this to me:
type IItem = interface end
type Item = {i:int} interface IItem
type Fail = static member foo (s:string) = fun (x:IItem) -> ""
let foo = fun (s:string) -> fun (x:IItem) -> ""
let works = {i=1} |> foo ""
let fails = {i=1} |> Fail.foo ""
Why does the currying with the static member function not work?
I'm using Visual Studio 2012 with .net 4.5.2 if that matters.
This isn't really a difference between static members and functions - it's a bit more subtle. Here's another repro:
type T =
static member A () (o:obj) = ()
static member B () = fun (o:obj) -> ()
T.A () 1 // ok
T.B () 1 // huh?
Note that the signatures of T.A and T.B are different (this is actually covered in section 11.2.1.1 of the spec):
type T =
class
static member A : unit -> o:obj -> unit
static member B : unit -> (obj -> unit)
end
This is a distinction that is usually unimportant, but basically it means that at a .NET representation level A is compiled to a method with two arguments (even though it looks curried in F#) while B is compiled to a method with a single argument which returns an F# function. This difference is ultimately what causes the behavior you're seeing.

Parameterless lambda expressions in F#

I am looking for a way to define Parameterless lambda expressions in F#, much like the following C# example.
var task = () => {
int x = 3;
DoSomething(x);
}
I tried the following
let task = fun _ ->
let x = 3
doSomething x
It compiles but it gives me task : ('a -> unit) what I am actually looking for is task : (unit -> unit)
The MSDN Documentation does not talk about this. What am I missing here ?
it's just
let task = fun () -> // whatever you need
you example would be:
let task = fun () ->
let x = 3
DoSomething(3)
assuming DoSomething is of type int -> unit - if it returns something else you need
let task = fun () ->
let x = 3
DoSomething(3) |> ignore
to get type unit -> unit
Remark:
Usually you don't write let task = fun () -> ... but just let task() = ...
The thing you missed:
if you write fun _ -> () you are saying you want to take some parameter that you don't mind about - so F# will take the most general (being named 'a here) - this would include unit!
() is the only value of type unit (more or less void from C# ... but a true type in F#)

Resources