Dans F #, comment puis-je attacher des métadonnées à des valeurs syndicales discriminées?
-
21-12-2019 - |
Question
Je veux créer quelque chose qui est un peu comme une énumération avec un type d'enregistrement F # pour une valeur au lieu d'une INT.Par exemple, si j'ai eu l'Union:
type BologneseIngredients = | Spaghetti
| Tomatoes
| MincedBeef
| GrandmasSecretIngredient
Je sais que Spaghetti est toujours de 30 cm de long et les tomates sont toujours rouges.Ce que je pouvais faire, c'est avoir une fonction 'Obtenir des métadonnées':
let getMetadata = function
| Spaghetti -> { length: 30.0<cm> }
| Tomatoes -> { colour: Color.Red }
| _ -> { }
Mais j'aimerais vraiment garder la définition de l'Union et des données ensemble.Y a-t-il une bonne façon de faire cela?
La solution
Ma suggestion:
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
Autres conseils
Vous pouvez ajouter des propriétés à votre union discriminée ...
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]
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow