是否可以在fsharp中动态生成Discriminated Union?

时间:2013-10-06 11:38:17

标签: dynamic f# discriminated-union

我正在研究在Fsharp中使用System.ComponentModel.Composition,并想知道是否有可能在内存中动态生成Discriminated Union?我想让DU构建出导入类型的元素。主要原因是我有一个DU工作的代码,我认为使用Composition最简单。我完全准备好接受这是错误的事情。

我过去曾使用FSharpTypeFSharpValue来处理各种事情,但似乎这些都是关于操纵现有的DU而不是创建新的DUs。

我很遗憾地说我还没有“我试过这个”代码示例,因为我不知道从哪里开始。

  • 有可能吗?
  • 可取吗?
  • 我是否真的使用DU代表来自Composition的内容?
  • 我很乐意使用反射,即使它有点慢。

修改

  • 是否可以/建议动态添加到DU? (如果必须存在DU)

1 个答案:

答案 0 :(得分:4)

有区别的联合的一大优点是在编译时已知可能的情况集,因此编译器可以告诉您何时代码无法处理可能的情况。这有助于重构,因为您可以向现有联合添加新案例,编译器将告诉您代码中需要更改的位置。

另一个好处是,区分联合的模式匹配在语法上很优雅 - 你可以编写非常清晰的代码。

理论上,您可以使用Reflection.emit动态生成DU,或者甚至可以将新案例添加到现有案例中。然而,上述两个优点都不适用,所以我根本没有看到使用它们的重点。

标准继承模型也是处理动态加载的插件IMO的正确方法。在每个插件所依赖的DLL中定义一个接口或公共基类,让插件定义一个实现它的类,然后在加载后在插件上使用该接口/基类上的方法。

DUs旨在提前修复可能/值/的集合,但是任何人都可以轻松地在DU上编写新函数,而面向对象的继承则用于修复可能的基本/函数集合。提前但让任何人都可以轻松添加新值。由于动态加载代码都是为了添加新值,我认为这非常适合。

值得一提的是,DUs实际上是由F#编译器使用.NET继承实现的 - 有一个基类用于整个联合类型,然后是每个联合案例的各个派生类(尽管我认为无参数案例得到特别对待。)