揭露受歧视的联盟案件的内容

时间:2017-06-14 15:56:19

标签: f#

我想知道是否有一种很好的方式将DU案例的内容暴露给DU类型本身。

例如:

befall_fallen-fell
Line - Eddying, dizzying, closing-round
Line - With soft and drunken laughter-laugh_laugh
laughter-laugh_laugh
Line - Veiling all that may befall_fallen-fell

重新审视我的设计后,就像Fyodor指出的那样,我决定为IShape创建一个界面。

[<Measure>] type inch

module StructuralShape =

    type Plate =
        {
        Length : float<inch>
        Thickness : float<inch>
        }

    type SingleAngle =
        {
        VerticalLeg : float<inch>
        HorizontalLeg : float<inch>
        Thickness : float<inch>
        }

    type StructuralShape =
        | Plate of Plate
        | SingleAngle of SingleAngle

    let area (ss : StructuralShape) =
        match ss with
        | Plate pl -> pl.Length * pl.Thickness
        | SingleAngle sa -> 
            (sa.HorizontalLeg + sa.VerticalLeg - sa.Thickness) * sa.Thickness

    type StructuralShape with
        member ss.Area = area ss

module Test =
    open StructuralShape

    let myShape = Plate {Length = 2.0<inch>; Thickness = 0.25<inch>}
    let area = myShape.Area

    // Looking to allow the user of the library
    // to access the internal shape properties
    // without having to use some type of 'get shape' function

    let length = myShape.Length  // fails

注意:为简单起见,这是库的简化版本。

2 个答案:

答案 0 :(得分:4)

目前还不清楚你想在这里实现什么目标。我怀疑你的设计中可能存在不一致的设计而没有意识到它。

如果您的StructuralShape类型只有一个案例,那么为什么还需要它?只需使用Plate代替!

如果您的StructuralShape类型会有更多案例,那么当实际值没有Thickness字段时会发生什么?

如果您的StructuralShape类型包含更多案例,但所有案例都必须包含Thickness字段,并且该字段具有相同类型且含义相同对于他们所有人来说,更好的设计就是“提升”。公共类型的公共字段,只留下DU下的差异:

type Plate = { Length: float }
type Foo = { Bar: string }

type StructuralShapeInfo = Plate of Plate | Foo of Foo

type StructuralShape = { Info: StructuralShapeInfo; Thickness: float }

(原谅我选择的Info后缀;我意识到这不是最好的选择,但我不能在不了解您的域名的情况下想出一个更好的选择虽然;编程中存在三个难题:命名内容和逐个错误)

答案 1 :(得分:2)

您可以增加与成员的歧视联盟,这对于在以下情况下方便访问很有用:

type StructuralShape =
    | Plate of Plate
    member this.Thickness = match this with Plate p -> p.Thickness

如果您向StructuralShape添加任何新案例,则需要在此属性的代码中处理该案例。

这可能是一个有用的事情,但是Fyodor在他关于重组数据模型的答案中提出了一个非常好的观点,因此这是不必要的。