设计一个可以从F#中使用的C#库的指南

jay*_*jay 12 c# f#

我只是想指出,这个问题不是相反的

设计F#库以供F#和C#使用的最佳方法

在这里,我不是要问如何设计一个用于两个世界的C#函数库.

我想知道什么样的设计选择包含或避免获得合理的折衷方案以使这个库可以从F#中使用的良好实践.

像(例如)的做法:

  • 保持对象层次结构尽可能简单

  • 避免改变对象的状态,但返回新的对象

  • 等等...

任何已经完成它的人都可以分享它的经验吗?

边注

有趣的是,这个OSS项目IronJS.是的,它是用F#编写的,但作者公开了两个专门的主机IronJS.Hosting.FSharpIronJS.Hosting.CSharp.

pad*_*pad 4

想象一下,有一天您想用 F# 重写 C# 库以获得更好的可用性。以下是您可能采取的路径:

在此输入图像描述

我重点关注路径“命令式 C# --> 函数式 C# --> 函数式 F# --> 惯用 F#”。您的 C# 库的功能越多,您的库在 F# 中的可用性就越高。函数式风格有助于提高可组合性,并且更接近惯用的 F# 代码。沿着这些思路,您可以:

  • 拥抱默认不变性原则。如果您不知道稍后是否需要更新某个字段/属性,只需readonly先标记它即可。
  • 遵循基于表达式和声明性的编程风格。LINQ 操作就是很好的例子。
  • 使用不可变集合或以不可变方式使用可变集合。随着C# 不可变集合的引入,它应该比以前更容易。

上图取自F# for fun andprofitPorting from C# to F#系列。他们非常乐于助人;了解 C# 概念如何在 F# 中表达将提高库的可用性。

C# 的面向对象特性是很难避免的。请记住,F# 类型推断不能很好地使用这些功能。为了保持对象层次结构简单,您应该减少成员重载的数量。大量成员重载很容易使 F# 类型检查器感到困惑。此外,用 C# 库分发一个精简的 F# 包装器也没什么坏处。您需要做的某些事情是将一些方法转换为模块函数并创建活动模式来分解对象层次结构。