12

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

设计用于 F# 和 C# 的 F# 库的最佳方法

在这里,我不是在问如何设计一个用 C# 编写的函数库,以便在两个世界中使用。

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

像(例如)这样的做法:

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

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

  • ETC...

有做过的人,可以分享一下经验吗?

边注

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

4

2 回答 2

4

与现有 .NET 库的互操作是 F# 的主要设计目标,因此对要使用的库没有任何限制。

也就是说,由于 F# 的类型更严格,有些模式会导致代码略显笨拙。建造者模式就是其中之一。

var bldr = new StringBuilder();
bldr.Append("abc"); //ignoring return value

对比

bldr.Append("abc") |> ignore //must be explicitly ignored

但这很容易使用扩展方法或 let-bound 函数解决。底线:互操作是 F# 的优势和最大成就之一。

于 2013-02-27T14:55:19.247 回答
4

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

在此处输入图像描述

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

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

上图取自F# 出于好玩和利益从 C# 到 F# 系列的移植。他们非常有帮助;了解 C# 概念在 F# 中的表达方式将提高库的可用性。

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

于 2013-02-27T17:46:36.217 回答