Question

Dans l'exemple du monde réel suivant, je fais un match:

type Style = Nice | Cool | Ugly
type Color = Blue | Yellow | Orange | Grey | Cyan
type ClothingProperties = Style * Color

type Clothes =
| Jeans of ClothingProperties
| Pullover of ClothingProperties
| Shirt of ClothingProperties

type Person =
| Person of string * Clothes

let team = [Person("Jan", Jeans (Cool, Blue)); Person("Pete", Shirt (Nice, Cyan)); Person("Harry", Pullover (Ugly, Grey))]

let matchPerson person=
    match person with
    | Person(name,  Jeans(Ugly,_) ) -> printfn "%s wears ugly stuff." name
    | Person(name,  Pullover(Ugly,_) ) -> printfn "%s wears ugly stuff." name
    | Person(name,  Shirt(Ugly,_) ) -> printfn "%s wears ugly stuff." name
    | _ -> ()

List.iter(fun x->matchPerson x) team

Y a-t-il un moyen de créer une correspondance plus efficace, donc je n'ai pas besoin de vérifier chaque cas de vêtements?Quelque chose comme ça:

let matchPerson person=
    match person with
    | Person(name,  _ (Ugly,_) ) -> printfn "%s wears ugly stuff." name
    | _ -> ()

Bien sûr, ce n'est pas une syntaxe correcte.Mais comment puis-je atteindre un tel effet?

Était-ce utile?

La solution

Ce n'est pas simple, vous pouvez utiliser la réflexion, mais le problème est que votre syndicat discriminé a besoin de la refonte de la refonte, car si vous savez qu'il y aura toujours des spécialistes de vêtements, vous pouvez le changer à ce sujet:

type Style = Nice | Cool | Ugly
type Color = Blue | Yellow | Orange | Grey | Cyan
type ClothingProperties = Style * Color // or just use a tuple

type Clothe =
| Jeans 
| Pullover
| Shirt

type Clothes = Clothe *ClothingProperties
type Person =
| Person of string * Clothes

let matchPerson person=
    match person with
    | Person(name,  (_,(Ugly,_)) ) -> printfn "%s wears ugly stuff." name
    | _ -> ()

Un problème connexe est décrit ici ici est-il possiblepasser des étiquettes union discriminées comme arguments?

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top