Skip to content

Instantly share code, notes, and snippets.

@Rickasaurus
Last active August 29, 2015 14:03
Show Gist options
  • Save Rickasaurus/b0868af40781cdfdef37 to your computer and use it in GitHub Desktop.
Save Rickasaurus/b0868af40781cdfdef37 to your computer and use it in GitHub Desktop.
Reflection Over Generic Methods (for invocation in Barb)
module FSharpExpr =
let getMethod =
function
| Patterns.Call (_, m, _) when m.IsGenericMethod -> m.GetGenericMethodDefinition()
| Patterns.Call (_, m, _) -> m
| _ -> failwith "Incorrect getMethod Pattern"
let X<'T> : 'T = Unchecked.defaultof<'T>
let inline application prms expr = Expr.Application(expr, prms)
let inline coerse typ expr = Expr.Coerce(expr, typ)
open FSharpExpr
let fx (x: 'a seq) = x
let fxType = <@@ fx X @@> |> getMethod
let fxPrms = fxType.GetParameters()
fxType.IsGenericMethod
let fy (y: 'b) = y
let fyType = <@@ fy X @@> |> getMethod
let fyPrms = fyType.GetParameters()
fxType.IsGenericMethod
let fxy (w: int) (x: 'a seq) (y: 'b) (q: int) = x
let fxyType = <@@ fxy X X X X@@> |> getMethod
let fxyPrms = fxyType.GetParameters()
fxyType.IsGenericMethod
let inline print (sq: 'a seq) = sq |> Seq.iter (printfn "pt: %A")
fxyPrms |> Seq.map (fun pi -> pi.ParameterType.ContainsGenericParameters) // True for both
fxyPrms |> Seq.map (fun pi -> pi.ParameterType.GenericParameterPosition) // throws on first prm
fyPrms |> Seq.map (fun pi -> pi.ParameterType.GenericParameterPosition) // seq [0]
fxyPrms |> Seq.map (fun pi -> pi.ParameterType.IsGenericParameter) // false true
fxyPrms |> Seq.map (fun pi -> pi.ParameterType.GetGenericArguments()) // [|a|] [||]
fxyPrms |> Seq.map (fun pi -> pi.ParameterType.IsGenericTypeDefinition) // false false
fxyPrms |> Seq.map (fun pi -> pi.ParameterType.IsGenericType) // true false
fxyType.GetGenericArguments() |> Seq.map (fun pi -> pi.Name) // ["a"] ["b"] (is lookup by name the best way?!!?!)
fxyPrms |> Seq.map (fun pi -> pi.ParameterType.GenericTypeArguments |> Seq.map (fun gta -> gta.Name)) //seq [seq ["a"]; seq []]
fxyPrms |> Seq.map (fun pi -> pi.ParameterType.FullName) //seq [null; null]
fxyPrms |> Seq.map (fun pi -> pi.ParameterType.Name) //seq ["IEnumerable`1"; "b"]
fxyType.GetGenericArguments() |> Seq.map (fun ga -> ga.GenericParameterPosition) // seq [0; 1] (HURRAY!!!)
fxyType.GetGenericArguments() |> Seq.map (fun ga -> ga.Name) // seq ["a"; "b"] (HURRAY!!!)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment