问题
I have a discriminated type:
type Item =
| Normal of string * float32
| Special1 of Item
| Special2 of Item
And I have a function using this type:
let rec calcItem (i: Item ) =
match i with
| Normal(_, p) -> p
| Special1(g) | Special2(g) -> (calcItem g) + 1
In my case, the Special_n types will be defined in the same form. So I am wondering if it is possible to use wildcard pattern to match all these types. The _
match does not work, because it does not accept arguments.
回答1:
Similar to this one and this one.
As explained there you can use reflection or redesign your DU (this is what I would recommend).
Reflection:
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
Redesign the 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
回答2:
You can try with active pattern:
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
This does not completely remove the need of matching each SpecialN case, but it separates it from the calcItem function
来源:https://stackoverflow.com/questions/24137032/f-and-negative-match