Coding Edgar
Coding Edgar

Reputation: 1465

Discriminated Union label to string

given the following Discriminated Union:

type A = B of string | C of int

How can I get the constructor B name?

A.B.ToString()
// would return something like:
val it : string = "FSI_0045+it@109-19"
// when I desire
val it : string = "B"

for example with this type it works:

type D = E | F

D.E.ToString();;
val it : string = "E"

I normally get the string name of an instance of the DU with

let stringFromDU (x: 'a) =
  match FSharpValue.GetUnionFields(x, typeof<'a>) with
  | case, _ -> case.Name

But in this case, I do not have an instance, I just want to serialize the label name.

Upvotes: 3

Views: 437

Answers (2)

scrwtp
scrwtp

Reputation: 13577

You're using FSharpValue from FSharp.Reflection namespace in your example. Note that there's another class in that library for handling scenarios where you want to work with types only, FSharpType.

let cases = FSharpType.GetUnionCases(typeof<A>)

Outside of unions, it also provides helpers for other operations on F# native types.

Upvotes: 1

CaringDev
CaringDev

Reputation: 8551

If you enable the latest language version, e.g. by passing --langversion:preview to FSI or setting

<PropertyGroup>
   <LangVersion>preview</LangVersion>
</PropertyGroup>

in your .fsproj, the following will work:

type A = B of int
let n = nameof A.B

Note: with F# 5 this will be supported out of the box :-)

Upvotes: 5

Related Questions