F # and negative match

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 types Special_n will be defined in the same form. So I'm wondering if you can use a lookup pattern to match all of these types. Mapping _does not work because it does not accept arguments.

+2
source share
2 answers

Like this and this .

As explained there, you can use reflection or reverse engineer 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

DU Redesign:

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
+7
source

:

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

+5

Source: https://habr.com/ru/post/1544560/


All Articles