3

在下面的現實世界的例子,我做一個匹配:通配符類型的匹配時,可識別聯合

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

當然,這是不正確的語法。但是我怎麼能達到這樣的效果呢?

回答

5

這不是簡單的,你可以使用反射,但問題是,你的歧視工會需要一些重新設計,因爲如果你知道總會有一個ClothingProperties,那麼你可以把它改成這樣:

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?

+0

這確實很有意義。謝謝。 –