我一直在观看一个有趣的视频,其中Haskell中的类型类用于解决所谓的"表达式问题".大约15分钟后,它显示了类型类如何用于"打开"基于区分联合扩展的数据类型 - 可以单独添加其他区分符,而无需修改/重建原始定义.
我知道F#中没有类型类,但有没有办法使用其他语言功能来实现这种可扩展性?如果没有,我们有多接近解决F#中的表达问题?
澄清:我假设问题的定义如同 系列的前一个视频所述 - 数据类型的可扩展性和数据类型的操作具有代码级模块化和单独编译的功能(扩展可以部署为单独的模块而不需要需要修改或重新编译原始代码)以及静态类型安全.
正如 J\xc3\xb6rg 在评论中指出的那样,这取决于您所说的解决的意思。如果你的意思是解决包括某种形式的类型检查,并且在某些情况下你不会缺少某些函数的实现,那么 F# 不会给你任何优雅的方式(而且我不确定 Haskell 是否解决方案很优雅)。您可以使用 kvb 提到的 SML 解决方案或使用基于 OO 的解决方案之一对其进行编码。
\n\n实际上,如果我正在开发一个需要解决问题的现实系统,我会选择一个不提供全面检查但更易于使用的解决方案。
\n\n草图将用作obj类型的表示,并使用反射来定位为个别情况提供实现的函数。我可能会使用某些属性来标记所有部分,以便于检查。将应用程序添加到表达式的模块可能如下所示:
[<Extends("Expr")>] // Specifies that this type should be treated as a case of \'Expr\'\ntype App = App of obj * obj\n\nmodule AppModule = \n [<Implements("format")>] // Specifies that this extends function \'format\'\n let format (App(e1, e2)) =\n // We don\'t make recursive calls directly, but instead use `invoke` function\n // and some representation of the function named `formatFunc`. Alternatively\n // you could support \'e1?format\' using dynamic invoke.\n sprintfn "(%s %s)" (invoke formatFunc e1) (invoke formatFunc e2)\nRun Code Online (Sandbox Code Playgroud)\n\n这不会为您提供任何类型检查,但它为您提供了一个相当优雅的解决方案,该解决方案易于使用且实现起来并不困难(使用反射)。检查是否没有遗漏案例并不是在编译时完成的,但您可以轻松地为此编写单元测试。
\n| 归档时间: |
|
| 查看次数: |
1082 次 |
| 最近记录: |