Card from discriminatory association to enumeration

I am currently trying to teach myself F # by creating an application composed of a C # GUI layer and an F # business layer. At the GUI level, the user has to make a choice at some point by selecting a value that is part of a simple enumeration, for example. by choosing one of the following values:

enum {One, Two, Three}

      

I wrote a function to convert an enum value to a delimited F # union

type MyValues = 
  | One
  | Two
  | Three

      

Now I need to translate back and I'm already tired of the template. Is there a general way to translate my discriminatory association into an appropriate listing and vice versa?

Greetings,

+3


source to share


2 answers


You can also define an enum in F # and do no conversions at all:

type MyValues = 
  | One = 0
  | Two = 1
  | Three = 2

      



The bit = <num>

tells the F # compiler to compile that type as a union. When using a C # type, this will appear as a perfectly normal enumeration. The only danger is that someone from C # might call your code with a help (MyValues)4

that will compile, but that will throw an incomplete template exception if you use match

in F #.

+6


source


Here are the common DU / enum converters.

open Microsoft.FSharp.Reflection

type Union<'U>() =
    static member val Cases = 
        FSharpType.GetUnionCases(typeof<'U>)
        |> Array.sortBy (fun case -> case.Tag)
        |> Array.map (fun case -> FSharpValue.MakeUnion(case, [||]) :?> 'U)

let ofEnum e = 
    let i = LanguagePrimitives.EnumToValue e
    Union.Cases.[i - 1]

let toEnum u = 
    let i = Union.Cases |> Array.findIndex ((=) u)
    LanguagePrimitives.EnumOfValue (i + 1)

let du : MyValues = ofEnum ConsoleColor.DarkGreen
let enum : ConsoleColor = toEnum Three

      



It maps the DU tag to the underlying enum value.

+1


source







All Articles