F#和负面匹配

Dav*_* S. 2 f# pattern-matching

我有一个歧视类型:

type Item =
    | Normal of string * float32
    | Special1 of Item
    | Special2 of Item
Run Code Online (Sandbox Code Playgroud)

我有一个使用这种类型的功能:

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

在我的情况下,Special_ ñ类型将在相同的形式进行定义.所以我想知道是否可以使用通配符模式来匹配所有这些类型.该_比赛是不行的,因为它不接受参数.

Gus*_*Gus 8

类似于这个这一个.

如上所述,你可以使用反射或重新设计你的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
Run Code Online (Sandbox Code Playgroud)

重新设计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
Run Code Online (Sandbox Code Playgroud)


Grz*_*cki 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
Run Code Online (Sandbox Code Playgroud)

这并不能完全消除匹配每个SpecialN情况的需要,但它将它与calcItem函数分开