It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened,
visit the help center.
Closed 7 years ago.
Please give an example of how to create new type (say, two types Cartesian product) in F# at runtime with reflection?
UPDATE
I am looking for a language with first class types. I was told F# can this. I tried nothing since didn't learned F# yet. I just want to see how it's made.
The following F# code takes 2 sequences of values (rank and suit in the example) and returns the cartesian product as a sequence of pairs (cards), using a pair type dynamically generated at runtime using Reflection:
open System
open System.Reflection
open System.Reflection.Emit
open Microsoft.FSharp.Reflection
/// Creates a dynamic module via reflection
let createModule () =
let name = Guid.NewGuid().ToString()
let d = AppDomain.CurrentDomain
let a = d.DefineDynamicAssembly(AssemblyName(name), AssemblyBuilderAccess.Run)
a.DefineDynamicModule(name)
/// Creates a dynamic pair type using the specified x and y types
let createPairType (x:Type, y:Type) =
let m = createModule()
let t = m.DefineType("Pair", TypeAttributes.Public ||| TypeAttributes.Class)
let x = t.DefineField(x.Name, x, FieldAttributes.Public)
let y = t.DefineField(y.Name, y, FieldAttributes.Public)
t.CreateType()
/// Creates a pair value using the specified pair type
let createPairValue (pairType:Type) (x:'X, y:'Y) =
let instance = Activator.CreateInstance(pairType)
pairType.GetField(typeof<'X>.Name).SetValue(instance, x)
pairType.GetField(typeof<'Y>.Name).SetValue(instance, y)
instance
/// Creates a cartesian product
let createCartesianProduct (xs:'X seq, ys:'Y seq) =
let pairType = createPairType (typeof<'X>,typeof<'Y>)
seq { for x in xs do for y in ys -> createPairValue pairType (x, y) }
/// Defines dynamic lookup operator for accessing a named field
let inline (?) (x:obj) name = x.GetType().GetField(name).GetValue(x)
/// Card suit discriminated union type
type Suit = Club | Diamond | Heart | Spade
/// Card rank discriminated union type
type Rank = | One | Two | Three | Four | Five | Six | Seven | Eight | Nine | Ten
| Jack | Queen | King | Ace
/// Gets union case values
let getUnionValues<'T>() =
FSharpType.GetUnionCases(typeof<'T>)
|> Seq.map (fun x -> FSharpValue.MakeUnion(x,[||]) :?> 'T)
let ranks, suits = getUnionValues<Rank>(), getUnionValues<Suit>()
/// Sequence of dynamically generated pairs
let cards = createCartesianProduct (ranks, suits)
// Paste this into F# interactive to print the generated cards
for card in cards do printfn "%A %A" card?Rank card?Suit
Taken from my (non-free) article Structural Typing in the F#.NET Journal:
The following createType function creates a new .NET assembly, new module and new public class type of the given name:
> let createType typeName =
let name = System.Reflection.AssemblyName(Name="tmpAssembly")
let run = System.Reflection.Emit.AssemblyBuilderAccess.Run
let builder = System.Threading.Thread.GetDomain().DefineDynamicAssembly(name, run)
let mdl = builder.DefineDynamicModule "tmpModule"
let attrs = TypeAttributes.Public ||| TypeAttributes.Class
mdl.DefineType(typeName, attrs);;
val createType : string -> TypeBuilder