如何将 F# 函数从 C# 应用程序传递到另一个 F# 函数?
我有 F# 类库程序集,其中包含两个函数:
let add a b = a + b
并且
let rec aggregateList list init (op:int -> int -> int) =
match list with
|[] -> init
|head::tail ->
let rest = aggregateList tail init op
op rest head
我有一个 C# 控制台应用程序,它引用 F# 库并尝试执行以下操作:
FSharpList<int> l = new FSharpList<int>(1, new FSharpList<int>(2, FSharpList<int>.Empty));
int result = myFsLibrary.aggregateList(l, 0, myFsLibrary.add);
但是,编译器抱怨 [myFsLibrary.add] 无法从“方法组”转换至 FSharpFunc
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
其他人已经提供了答案,但我只想说你不应该这样做。
不要将 F# 列表公开给 C#。不要向 C# 公开柯里化函数。阻抗不匹配在此边界处是可见的,因此最好在跨语言汇编边界处公开通用框架类型。请参阅
http://research.microsoft.com /en-us/um/cambridge/projects/fsharp/manual/fsharp-component-design-guidelines.pdf
获取更多建议。
Other people have provided answers, but I'll just step in to say that you shouldn't do this.
Don't expose F# lists to C#. Don't expose curried functions to C#. The impedance mismatch is visible at this boundary, so it is better to expose common framework types at cross-language assembly boundaries. See
http://research.microsoft.com/en-us/um/cambridge/projects/fsharp/manual/fsharp-component-design-guidelines.pdf
for more advice.
您可以使用
FSharpFunc
委托显式创建函数。在 C# 中,创建将所有参数作为元组的函数会更方便,因此您可以这样做,然后使用FuncConvert
将函数转换为柯里化类型。例如:但是,如果您需要从 C# 代码调用某些 F# 函数,建议公开具有 C# 友好接口的函数。在这种情况下,您可以使用
Func
委托,并且第一个参数应该是IEnumerable
而不是 F# 特定的列表类型:然后您的 C# 应用程序可以使用:
You can explicitly create a function using the
FSharpFunc
delegate. In C#, it is more convenient to create function that takes all arguments as a tuple, so you can do that and then convert the function to a curried type usingFuncConvert
. Something like:However, if you need to call some F# function from your C# code, it is recommended to expose a function with a C#-friendly interface. In this case, I you can use
Func
delegate and the first argument should beIEnumerable
instead of F#-specific list type:Then your C# appplication can just use:
原因是 add 被导出为普通的 .Net 风格函数,并具有粗略的
C# 签名,并且大多数 .Net 语言将其视为采用 2 个
int
参数并返回单个 <代码>int值。但 F# 并不以这种方式看待函数。相反,它将add
视为一个函数,它接受一个int
并返回一个函数,该函数又接受一个int
并返回一个int.这种函数视图使得实现柯里化等操作变得非常容易。
为了从 C# 世界观转换为 F# 世界观,您需要使用一些魔法将方法折叠到自身上。我通过定义一组 F# 工厂和扩展方法来实现这一目标,为我带来神奇的效果。例如,
我可以使用此库为
add
方法获取适当的 F# 委托类型,如下所示The reason why is that add is exported as a normal .Net style function and has the rough signature
C#, and most .Net languages, see this as a method which takes 2
int
parameters and returns a singleint
value. F# though doesn't see functions this way. Instead it seesadd
as a function takes anint
and returns a function which in turn takse anint
and returns anint
. This view of functions makes it very easy to implement operations like currying.In order to convert from the C# view of the world to F# you need to do a bit of magic to fold a method onto itself. I accomplish this by defining a set of F# factory and extension methods to do the magic for me. For example
I can use this library to get the appropriate F# delegate type for the
add
method like so