Question

Suppose I've defined the following interface in F#:

type IFoo<'T> = 
  abstract member DoStuff : 'T -> unit

If I implement this in C# I need the method signature to be:

public void DoStuff<T>(T arg) {...}

What I really want to do is reference FSharp.Core and then use:

public Unit DoStuff<T>(T arg) {...}

This would simplify other code because I wouldn't have to deal with Action vs Func. I'm guessing that there isn't any clean way to achieve this? How about some evil hacks?

Was it helpful?

Solution

Transformation of Unit to void is baked into the compiler. There's a FuncConvert class in F# Core for converting between FSharpFunc and Converter. What about defining a similar class to convert Action<T> to Func<T, Unit>?

static class ActionConvert {
    private static readonly Unit Unit = MakeUnit();

    public static Func<T, Unit> ToFunc<T>(Action<T> action) {
        return new Func<T, Unit>(x => { action(x); return Unit; });
    }

    private static Unit MakeUnit() {
        //using reflection because ctor is internal
        return (Unit)Activator.CreateInstance(typeof(Unit), true);
    }
}

Then you could do

var foo = new Foo<int>();
var func = ActionConvert.ToFunc<int>(foo.DoStuff);

You could probably even forego the Unit instance and return null instead.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top