2014-06-10 66 views
2

我有一個辨別的類型:F#和消極比賽

type Item = 
    | Normal of string * float32 
    | Special1 of Item 
    | Special2 of Item 

而且我一直在使用這種類型的函數:

let rec calcItem (i: Item) = 
    match i with 
    | Normal(_, p) -> p 
    | Special1(g) | Special2(g) -> (calcItem g) + 1 

在我的情況下,Special_ ň類型會以相同的形式定義。所以我想知道是否可以使用通配符模式來匹配所有這些類型。 _匹配不起作用,因爲它不接受參數。

+0

您在示例代碼 –

+0

@GrzegorzSławecki,thx;中得到了重複的Special1;) – davidshen84

回答

7

類似於this onethis one

如上所述,您可以使用反射或重新設計您的DU(這是我會推薦的)。

反思:

open Microsoft.FSharp.Reflection 

type Item = 
    | Normal of string * float32 
    | Special1 of Item 
    | Special2 of Item 

let innerValue a = 
    FSharpValue.GetUnionFields (a, a.GetType()) 
    |> snd 
    |> Seq.head 
    :?> Item 

let rec calcItem (i: Item) = 
    match i with 
    | Normal (_, p) -> p 
    | specialN  -> calcItem (innerValue specialN) + 1.0f 

重新設計DU:

type Item = 
    | Normal of string * float32 
    | Special of int * Item 

let rec calcItem (i: Item) = 
    match i with 
    | Normal (_, p) -> p 
    | Special (_, g) -> calcItem g + 1.0f 
5

你可以用主動模式嘗試:

type Item = 
    | Normal of string * float32 
    | Special1 of Item 
    | Special2 of Item 

let (|Special|Norm|) (item) = 
    match item with 
    | Special1(g) | Special2(g) -> Special(g) 
    | _ -> Norm 

let rec calcItem (i: Item) = 
    match i with 
    | Normal(_, p) -> p 
    | Special(g) -> (calcItem g) + 1.0f 

這並不完全刪除每個SpecialN情況相匹配的需要,但它將它與calcItem函數分開