歧视联盟中的不可变领域

时间:2011-09-09 11:23:51

标签: f# record discriminated-union

我知道可以为有区别的联合添加方法和属性,但是你可以添加一个必须在创建联合的实例时设置的不可变字段,就像记录中的字段一样吗?

我想我想要做的是结合联合类型和记录类型,如下所示:

type union =
    | OptionOne of int
    | OptionTwo of string
    {
        AFieldUsedForBothCases : string
    }

这不是有效的声明。

我知道这可以通过创建记录类型来解决:

type record =
    {
        AFieldUsedForBothCases : string
        TheDiscriminatedUnion : union
    }

但如果可能的话,我想做第一个例子。

3 个答案:

答案 0 :(得分:5)

不,我不这么认为,但你可以将它附加到两个案例中并用成员提取它:

type union =
    | OptionOne of int * string
    | OptionTwo of string * string
    member u.AFieldUsedForBothCases =
        match u with
        | OptionOne (_,s) | OptionTwo(_,s) -> s

最后,您必须在构造函数中指定其他元素。好吧,这个会让你在每个构造函数上重新键入公共元素,但我认为它并没有那么糟糕。

答案 1 :(得分:3)

我认为这是一个更简洁的解决方案

type union=
|a of int
|b of string

type Realtype = string * union

感谢类型检查,您可以强制进行属性设置,我认为它比记录解决方案更整洁

答案 2 :(得分:1)

我认为这是不可能的。除了我认为你的第二个代码(使用记录)更有意义,因为DUs是关于“这个或那个或那......”,现在如果在所有这些情况之间存在共同点,那么我将保留那个常见的东西离开DU而不是DU。