Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Discriminated Union label to string

Tags:

f#

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.

like image 293
Coding Edgar Avatar asked Nov 26 '25 09:11

Coding Edgar


2 Answers

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 :-)

like image 53
CaringDev Avatar answered Nov 28 '25 17:11

CaringDev


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.

like image 31
scrwtp Avatar answered Nov 28 '25 16:11

scrwtp



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!