我想创建一些类似于带有F#记录类型的枚举的东西,而不是int。例如,如果我有工会:
type BologneseIngredients = | Spaghetti
| Tomatoes
| MincedBeef
| GrandmasSecretIngredient
我知道意大利面总是长30厘米,西红柿总是红的。我能做的是拥有'获取元数据'功能:
let getMetadata = function
| Spaghetti -> { length: 30.0<cm> }
| Tomatoes -> { colour: Color.Red }
| _ -> { }
但我真的想将联合和数据的定义保持在一起。有没有一个很好的方法来做到这一点?
答案 0 :(得分:3)
您可以为受歧视的联盟添加属性......
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]
答案 1 :(得分:2)
我的建议:
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