vendredi 25 janvier 2019

How can I use reflection to determine if an F# union type is an enum-like union (no fields in each case)

Terminology

For the following post, I will use the term "reference enum" to refer to an F# type that is a discriminated union with no fields in each case. For example:

type AReferenceEnum = Yes | No | Maybe


Requirements

I need a function that given a Type, returns a bool that tells whether the type is a reference enum or not.

Given these types:

type AReferenceEnum = Yes | No | Maybe

type ARecord = { name : string }

type AUnion = This of int | That of (int * string)

type AEnum = Left = 1 | Right = 2

The function would return these values

isReferenceEnum typeof<AReferenceEnum> -> true

isReferenceEnum typeof<ARecord> -> false

isReferenceEnum typeof<AUnion> -> false

isReferenceEnum typeof<AEnum> -> false


What I've tried

It seems like the implementation could be done using FSharpType and FSharpValue in the FSharp.Reflection namespace.

I know you can check FSharpType.IsUnion t to check if a type is a union, which includes reference enums.

I know you can check FSharpType.GetUnionCases t to get a UnionCaseInfo[] describing the different cases of the union type.

I know you can check FSharpValue.GetUnionFields (value, type) to get the fields of the case that value is an instance of, but not other cases.

If I could iterate the fields of each case of the union, then I could check that all cases have 0 fields, and then the type would be a reference enum.

Any suggestions?





Aucun commentaire:

Enregistrer un commentaire