Friday, May 08, 2015

Getting the types in an F# union type II -- the perils of relying on undocumented implementation details

Recalling this example --


It was adequate for the use case I had of it at the time; but then I tried a different union type, at which point a bug showed up



yields

FSI_0003+Card
System.NullReferenceException: Object reference not set to an instance of an object.
   at FSI_0005.it@24-1.Invoke(Type x)
   at Microsoft.FSharp.Collections.SeqModule.Iterate[T](FSharpFunc`2 action, IEnumerable`1 source)
   at .$FSI_0005.main@()
Stopped due to error

And, of course, that is exactly what I deserved for relying on the undocumented internals.

A quick decompilation reveals this to be because union cases that carry no data are actually concrete base type instances, bearing the tag number as data, like --



rather than being redundant empty subtypes.

So we need to tweak our function to be




and all is well. For the moment. Until the representation changes.

No comments :