Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the Enum.GetName equivalent for F# union member?

Tags:

I want to get the equivalent of Enum.GetName for an F# discriminated union member. Calling ToString() gives me TypeName+MemberName, which isn't exactly what I want. I could substring it, of course, but is it safe? Or perhaps there's a better way?

like image 821
Dmitri Nesteruk Avatar asked Aug 11 '09 08:08

Dmitri Nesteruk


People also ask

How do you find the value of an enum?

To get the value of enum we can simply typecast it to its type. In the first example, the default type is int so we have to typecast it to int. Also, we can get the string value of that enum by using the ToString() method as below.

Can enum string value?

The enum can be of any numeric data type such as byte, sbyte, short, ushort, int, uint, long, or ulong. However, an enum cannot be a string type.

Can we convert enum to string in C#?

We can convert an enum to string by calling the ToString() method of an Enum.


2 Answers

You need to use the classes in the Microsoft.FSharp.Reflection namespace so:

open Microsoft.FSharp.Reflection  ///Returns the case name of the object with union type 'ty. let GetUnionCaseName (x:'a) =      match FSharpValue.GetUnionFields(x, typeof<'a>) with     | case, _ -> case.Name    ///Returns the case names of union type 'ty. let GetUnionCaseNames <'ty> () =      FSharpType.GetUnionCases(typeof<'ty>) |> Array.map (fun info -> info.Name)  // Example type Beverage =     | Coffee     | Tea  let t = Tea > val t : Beverage = Tea  GetUnionCaseName(t) > val it : string = "Tea"  GetUnionCaseNames<Beverage>() > val it : string array = [|"Coffee"; "Tea"|] 
like image 103
Daniel Asher Avatar answered Oct 11 '22 10:10

Daniel Asher


@DanielAsher's answer works, but to make it more elegant (and fast? because of the lack of reflection for one of the methods), I would do it this way:

type Beverage =     | Coffee     | Tea     static member ToStrings() =         Microsoft.FSharp.Reflection.FSharpType.GetUnionCases(typeof<Beverage>)             |> Array.map (fun info -> info.Name)     override self.ToString() =         sprintf "%A" self 

(Inspired by this and this.)

like image 27
ympostor Avatar answered Oct 11 '22 10:10

ympostor