Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/fsharp/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在F#中,如何将元数据附加到已区分的联合值?_F#_Discriminated Union - Fatal编程技术网

在F#中,如何将元数据附加到已区分的联合值?

在F#中,如何将元数据附加到已区分的联合值?,f#,discriminated-union,F#,Discriminated Union,我想创建一种类似于枚举的东西,其值的记录类型为F#而不是int。例如,如果我有并集: type BologneseIngredients = | Spaghetti | Tomatoes | MincedBeef | GrandmasSecretIngredient 我知道意大利面总是30厘米长,西红柿总是红色的。我可以做的是使

我想创建一种类似于枚举的东西,其值的记录类型为F#而不是int。例如,如果我有并集:

type BologneseIngredients = | Spaghetti
                            | Tomatoes
                            | MincedBeef
                            | GrandmasSecretIngredient
我知道意大利面总是30厘米长,西红柿总是红色的。我可以做的是使用“获取元数据”功能:

let getMetadata = function
                    | Spaghetti -> { length: 30.0<cm> }
                    | Tomatoes -> { colour: Color.Red }
                    | _ -> { }
让getMetadata=function
|意大利面->{长度:30.0}
|西红柿->{Color:Color.Red}
| _ -> { }

但是我真的想把联合的定义和数据放在一起。有什么好方法可以做到这一点吗?

您可以将属性添加到受歧视的联合中

type BologneseIngredients = 
    | Spaghetti
    | Tomatoes
    | MincedBeef
    | GrandmasSecretIngredient

    member x.Color =
        match x with
        | Spaghetti -> Color.AntiqueWhite
        | Tomatoes -> Color.Red
        | MincedBeef -> Color.Firebrick
        | GrandmasSecretIngredient -> Color.Transparent



let foo = Tomatoes

printfn "%A" foo.Color

> Color [Red]

您可以将属性添加到受歧视的联合中

type BologneseIngredients = 
    | Spaghetti
    | Tomatoes
    | MincedBeef
    | GrandmasSecretIngredient

    member x.Color =
        match x with
        | Spaghetti -> Color.AntiqueWhite
        | Tomatoes -> Color.Red
        | MincedBeef -> Color.Firebrick
        | GrandmasSecretIngredient -> Color.Transparent



let foo = Tomatoes

printfn "%A" foo.Color

> Color [Red]
我的建议是:

module Recipes =

    type BologneseIngredients = | Spaghetti
                                | Tomatoes
                                | MincedBeef
                                | GrandmasSecretIngredient

    let length (ind : BologneseIngredients) : float<cm> option =
         match ind with
         | Sphaghetti -> Some 30.0<cm>
         | _ -> None

    // .. or a bit more "metadata"ish
    type Metadata = 
        | Length of float<cm>
        | Color of System.Drawing.Color

    let metadata = 
       function
       | Sphaghetti -> [ Length 30.0<cm ]
       | Tomatoes   -> [ Color System.Drawing.Color.Red ]
       | ...

    let metaLength meta =
       meta |> List.tryPick (function | Length l -> Some l | _ -> None)

    let getLength = metadata >> metaLength
模块配方=
输入博洛尼亚配料=|意大利面
|西红柿
|肉末牛肉
|大量分泌
让长度(ind:Bolognese配料):浮动选项=
匹配
|斯帕格赫蒂->约30.0
|无
// .. 或者更“元数据”一点
类型元数据=
|浮子长度
|系统的颜色。绘图。颜色
让元数据=
功能
|Sphaghetti->[长度30.0[颜色系统.绘图.颜色.红色]
| ...
让metaLength meta=
meta |>List.tryPick(函数|长度l->部分l | | |->无)
让getLength=元数据>>metaLength
我的建议:

module Recipes =

    type BologneseIngredients = | Spaghetti
                                | Tomatoes
                                | MincedBeef
                                | GrandmasSecretIngredient

    let length (ind : BologneseIngredients) : float<cm> option =
         match ind with
         | Sphaghetti -> Some 30.0<cm>
         | _ -> None

    // .. or a bit more "metadata"ish
    type Metadata = 
        | Length of float<cm>
        | Color of System.Drawing.Color

    let metadata = 
       function
       | Sphaghetti -> [ Length 30.0<cm ]
       | Tomatoes   -> [ Color System.Drawing.Color.Red ]
       | ...

    let metaLength meta =
       meta |> List.tryPick (function | Length l -> Some l | _ -> None)

    let getLength = metadata >> metaLength
模块配方=
输入博洛尼亚配料=|意大利面
|西红柿
|肉末牛肉
|大量分泌
让长度(ind:Bolognese配料):浮动选项=
匹配
|斯帕格赫蒂->约30.0
|无
//…或者更“元数据”一点
类型元数据=
|浮子长度
|系统的颜色。绘图。颜色
让元数据=
功能
|Sphaghetti->[长度30.0[颜色系统.绘图.颜色.红色]
| ...
让metaLength meta=
meta |>List.tryPick(函数|长度l->部分l | | |->无)
让getLength=元数据>>metaLength

你可以附加你常用的属性,但这更没有功能;)…我会把所有的东西都收集到一个漂亮的模块中,然后制作
长度
颜色
,等等。只需一个函数或者只需制作
属性类型(
类型成分={length:float…}`然后为你的
BologneseComponents
创建一个函数或一个成员。我喜欢你的第一个选项。因此长度是一个函数:键入length=Components->float选项,然后只对不适用的属性返回None。很好!如果你为这些建议输入答案,我会将其标记为已回答。谢谢你的帮助!你可以附加您常用的属性,但这更没有功能;)…我会将所有内容收集到一个漂亮的模块中,并制作
length
color
,等等。只需一个函数或只需制作
attributes'类型(
type-components={length:float…}`为你的
BologneseComponents
创建一个函数或一个成员。我喜欢你的第一个选项。因此长度是一个函数:键入length=Components->float选项,然后在不适用的属性中返回None。太好了!如果你为这些建议输入答案,我会将其标记为已回答。谢谢你的帮助!