匹配区别联合时的通配符

时间:2014-04-11 09:47:07

标签: f# functional-programming pattern-matching discriminated-union

在下面的真实世界示例中,我进行了匹配:

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

有没有办法创造更有效的比赛,所以我不需要检查每件衣服?像这样:

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

当然,这不是正确的语法。但是我怎么能达到这样的效果呢?

1 个答案:

答案 0 :(得分:5)

这不是直截了当的,你可以使用反射,但问题是你的歧视联盟需要重新设计,因为如果你知道总会有一个服装属性,那么你可以将它改为:

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
    | _ -> ()

此处描述了相关问题Is it possible to pass discriminated union tags as arguments?