Dans F #, comment puis-je attacher des métadonnées à des valeurs syndicales discriminées?

StackOverflow https://stackoverflow.com//questions/25059587

  •  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?

Était-ce utile?

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
scroll top