In F #, come posso allegare i metadati a valori dell'Unione discriminati?
-
21-12-2019 - |
Domanda
Voglio creare qualcosa che sia un tipo come un enum con un tipo di record F # per un valore invece di un int.Ad esempio, se ho l'unione:
type BologneseIngredients = | Spaghetti
| Tomatoes
| MincedBeef
| GrandmasSecretIngredient
.
So che gli spaghetti sono sempre lunghi 30 cm e i pomodori sono sempre rossi.Quello che potrei fare è avere una funzione "ottieni metadati":
let getMetadata = function
| Spaghetti -> { length: 30.0<cm> }
| Tomatoes -> { colour: Color.Red }
| _ -> { }
.
Ma mi piacerebbe davvero mantenere la definizione dell'Unione e i dati insieme.C'è un bel modo per farlo?
Soluzione
Il mio suggerimento:
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
. Altri suggerimenti
Potresti aggiungere proprietà alla tua Unione discriminata ...
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]
. Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow