Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to adapt Action<string> into FSharpFunc<string, unit>

Tags:

c#

.net

f#

Attempts to pass an Action to F# code is producing the following syntax error in .net 4.6.1, VS2015...

Error   CS1503  Argument 1: 
cannot convert from 'System.Action<string>' to 
'Microsoft.FSharp.Core.FSharpFunc<string, Microsoft.FSharp.Core.Unit>'

The attempts are as follows...

using Microsoft.FSharp.Core;

....

Action<string> logger = Console.WriteLine;

App.perform(new Action<string>(Console.WriteLine), args);

App.perform(logger, args);

App.perform(new Action<string>(msg => Console.WriteLine(msg)), args);

App.perform((new Action<string>(msg => Console.WriteLine(msg))), args);

App.perform((new Func<string,Unit>(msg => Console.WriteLine(msg))), args);

App.perform(new Func<string,Unit>(Console.WriteLine), args);

What is the proper way to pass System.Console.WriteLine from C# to F#?

like image 599
George Avatar asked Mar 25 '19 01:03

George


2 Answers

Microsoft.FSharp.Core.FuncConvert provides various conversion/adapter function, one of them can adapt Action<string> to FSharpFunc<string, unit>.

// Reference: FSharp.Core.dll
var writeLine = Microsoft.FSharp.Core.FuncConvert.FromAction<string>(Console.WriteLine);
App.perform (writeLine);

The problem is that the Action<string> delegate and FSharpFunc<string, unit> class are unrelated as far as the runtime is concerned although we know they are conceptually close. C# unfortunately has not added any support to help with F# interoperability.

like image 166
Just another metaprogrammer Avatar answered Oct 03 '22 02:10

Just another metaprogrammer


You have to convert Action<T> to F# FSharpFunc<T>. This is a must, because all Lambda function in F# is using FSharpFunc under the hood, and they are not having the same semantic.

like image 45
Eriawan Kusumawardhono Avatar answered Oct 03 '22 02:10

Eriawan Kusumawardhono