Last active
September 6, 2018 22:30
-
-
Save kevmal/e29dbf6431af2e23f26d6480f8e17b82 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
open Microsoft.FSharp.Quotations | |
open System | |
type TypeTemplate() = | |
static member create ([<ReflectedDefinition(false)>] f : Expr<'a -> 'b>) : Type list -> ('a -> 'b) = | |
let rec extractCall e = | |
match e with | |
| Patterns.Lambda(_,body) -> extractCall body | |
| Patterns.Call(_o,minfo,_args) -> minfo | |
| _ -> failwithf "Expression not of expected form %A" e | |
let rec replaceMethod minfo e = | |
match e with | |
| Patterns.Lambda(v,body) -> Expr.Lambda(v, replaceMethod minfo body) | |
| Patterns.Call(Some o,_,args) -> Expr.Call(o,minfo,args) | |
| Patterns.Call(None,_,args) -> Expr.Call(minfo,args) | |
| _ -> failwithf "Expression not of expected form %A" e | |
match f with | |
| Patterns.Lambda (_,e) -> | |
let minfo = extractCall e | |
let makeMethod = | |
if minfo.IsGenericMethod then | |
let minfodef = minfo.GetGenericMethodDefinition() | |
fun types -> | |
minfodef.MakeGenericMethod(types |> Seq.toArray) | |
else | |
fun _ -> minfo | |
fun types -> | |
let method = makeMethod types | |
let lambda = replaceMethod method f | |
FSharp.Linq.RuntimeHelpers.LeafExpressionConverter.EvaluateQuotation lambda :?> ('a -> 'b) | |
| _ -> failwithf "Expression not of expected form %A" f | |
//Example | |
let testExpr<'t1,'t2,'t3> arg1 arg2 arg3 = | |
<@@ | |
printfn "%s" ((%%arg1 : 't1).ToString()) | |
printfn "%s" ((%%arg2 : 't2).ToString()) | |
printfn "%s" ((%%arg3 : 't3).ToString()) | |
@@> | |
let bleh = | |
<@@ | |
printfn "bleh" | |
%%(TypeTemplate.create testExpr<_,_,_> [typeof<string>; typeof<double>; typeof<int>] <@@"bleh"@@> <@@1.0@@> <@@5@@>) : unit | |
@@> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment