Search code examples
reflectionf#reflection.emittype-providersdiscriminated-union

Using Reflection.Emit to generate Discriminated Unions


I would like to know if it was possible to generate a DU in f# using Reflection.emit (or anything else there is out there) or even add new cases to an already defined DU.

I have been looking at the msdn website, and I found out that all I can do is to get union cases or create union cases. Either by using FSharpValue.MakeUnion or using quotations with Expr.NewUnionCase to create them.

The issue I have with using this methods is how would I be able to bind them in such a way that the union cases I have made belong to the same DU? Maybe that is not the right to way to undertake this problem. In that case how would I generate DU dynamically?

P.S: The goal would be to generate DUs inside a Type provider. This would mean, if I am not wrong, that when compiled into a .dll file, I would be able to access the DU generated by the TypeProvider inside a script file. Thus meaning that I would be able to apply pattern matching over an instance of the DU, and also get the type safety provided by the DU (exhaustiveness of all the cases in a pattern matching for instance).


Solution

  • I would have a look at the F# Compiler Services to generate discriminated unions dynamically. Basically, you're relying on the F# compiler to generate the required types. My limited understanding is that both records and discriminated unions require some sort of assembly metadata outside the type for the F# compiler to recognise them as such. If you went down the Reflection.Emit route you would need to make sure that any generated assemblies have this metadata if its possible via that API.

    Type providers can't expose records and discriminated unions right now as of F# 4.0. There's a F# Uservoice suggestion for it; but it will probably be awhile before it makes it into the language. What I would do is generate a union with the compiler services above, and add a "Match" member with the pattern match inside of it. It won't be an official "DU" when it goes through the type provider mechanism but will still work.