【问题标题】:How to adapt Action<string> into FSharpFunc<string, unit>如何将 Action<string> 改编为 FSharpFunc<string, unit>
【发布时间】:2019-03-25 01:13:11
【问题描述】:

尝试将 Action 传递给 F# 代码会在 .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>'

尝试如下……

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

System.Console.WriteLine 从 C# 传递到 F# 的正确方法是什么?

【问题讨论】:

  • 我不清楚,你想做什么?您是否尝试从 F# 打印到控制台?
  • 正如错误消息非常清楚地指出的那样,F# 函数需要FSharpFunc&lt;_&gt; 类型的参数。为什么你一直试图将ActionFunc 传递给它?
  • 我使用C# 包装器通过我最近开发的F# 库访问VS2015 中的部署基础架构。该库接受Console.WriteLine 符合要求的记录器。我想一种选择是直接从库中访问Console.WriteLine。但是,将void 强制转换为unit 很有用。

标签: c# .net f#


【解决方案1】:

Microsoft.FSharp.Core.FuncConvert提供多种转换/适配功能,其中一种可以将Action&lt;string&gt;适配成FSharpFunc&lt;string, unit&gt;

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

问题在于Action&lt;string&gt; 委托和FSharpFunc&lt;string, unit&gt; 类在运行时方面是不相关的,尽管我们知道它们在概念上很接近。遗憾的是,C# 没有添加任何支持来帮助 F# 互操作性。

【讨论】:

  • 感谢您提供功能性和参考性示例。我很晚才开始怀疑,如果有必要,调整只会存在于 F# 包装中,但发现使用我目前的工具需要付出一些努力。再次感谢。
  • 仅供参考;你也可以实现抽象类FSharpFunc。我的第一次尝试是这样做的,但后来我找到了一个合适的辅助方法。
  • 那会很好,但只是补充。揭示FuncConvert 模块,从而解决此问题的F# 解决方案模式是最好的答案。 :)
【解决方案2】:

您必须将 Action&lt;T&gt; 转换为 F# FSharpFunc&lt;T&gt;。这是必须的,因为 F# 中的所有 Lambda 函数都在后台使用 FSharpFunc,并且它们的语义不同。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-06-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多