1 people like it.

Using Expressions to Clone F# Values

How to generate functions for copying F# record-array-union trees with Expr.

  1: 
  2: 
  3: 
  4: 
  5: 
  6: 
  7: 
  8: 
  9: 
 10: 
 11: 
 12: 
 13: 
 14: 
 15: 
 16: 
 17: 
 18: 
 19: 
 20: 
 21: 
 22: 
 23: 
 24: 
 25: 
 26: 
 27: 
 28: 
 29: 
 30: 
 31: 
 32: 
 33: 
 34: 
 35: 
 36: 
 37: 
 38: 
 39: 
 40: 
 41: 
 42: 
 43: 
 44: 
 45: 
 46: 
 47: 
 48: 
 49: 
 50: 
 51: 
 52: 
 53: 
 54: 
 55: 
 56: 
 57: 
 58: 
 59: 
 60: 
 61: 
 62: 
 63: 
 64: 
 65: 
 66: 
 67: 
 68: 
 69: 
 70: 
 71: 
 72: 
 73: 
 74: 
 75: 
 76: 
 77: 
 78: 
 79: 
 80: 
 81: 
 82: 
 83: 
 84: 
 85: 
 86: 
 87: 
 88: 
 89: 
 90: 
 91: 
 92: 
 93: 
 94: 
 95: 
 96: 
 97: 
 98: 
 99: 
100: 
101: 
102: 
103: 
104: 
105: 
106: 
107: 
108: 
109: 
110: 
#r "System.Data.Linq" 

open System
open System.Reflection
open System.ComponentModel
open System.Linq.Expressions
open Microsoft.FSharp.Reflection
open Microsoft.FSharp.Quotations

module FSharpType = 
    let IsOption (stype: System.Type) = stype.Name = "FSharpOption`1"

module RecordCloning = 
    let inline application prms expr = Expr.Application(expr, prms)
    let inline coerse typ expr = Expr.Coerce(expr, typ)
    let inline newrec typ args = Expr.NewRecord(typ, args)

    let (|IsMapType|_|) (t: Type) = 
        if t.IsGenericType && t.GetGenericTypeDefinition() = typedefof<Map<_,_>> then Some t
        else None    

    let rec copyThing (mtype: Type) : Expr = 
        match mtype with 
        | _ when FSharpType.IsRecord mtype -> genRecordCopier mtype
        | _ when FSharpType.IsUnion mtype  -> genUnionCopier mtype 
        | _ when mtype.IsValueType || mtype = typeof<String> -> getIdFunc mtype
        | _ when mtype.IsArray -> genArrayCopier mtype
        | IsMapType t -> getIdFunc mtype
        | _ when mtype = typeof<System.Object> -> getIdFunc mtype
        | _ -> failwithf "Unexpected Type: %s" (mtype.ToString())

    and X<'T> : 'T = Unchecked.defaultof<'T>

    and getMethod = 
        function
        | Patterns.Call (_, m, _) when m.IsGenericMethod -> m.GetGenericMethodDefinition()
        | Patterns.Call (_, m, _) -> m
        | _ -> failwith "Incorrect getMethod Pattern"

    and getIdFunc itype =
        let arg = Var("x", itype, false)
        let argExpr = Expr.Var(arg)        
        let func = 
            let m = (getMethod <@ id X @>).MakeGenericMethod([|itype|])
            Expr.Call(m, [argExpr])
        Expr.Lambda(arg, func)

    and genRecordCopier (rtype: Type) : Expr =         
        let arg = Var("x", rtype, false)
        let argExpr = Expr.Var(arg) 
        let newrec =            
            FSharpType.GetRecordFields(rtype) |> Array.toList
            |> List.map (fun field -> genFieldCopy argExpr field)
            |> newrec rtype
        Expr.Lambda(arg, newrec)

    and genFieldCopy argExpr (field: PropertyInfo) : Expr = 
        let pval = Expr.PropertyGet(argExpr, field) 
        copyThing field.PropertyType |> application pval
             
    and genArrayCopier (atype : Type) : Expr = 
        let etype = atype.GetElementType()        
        let copyfun = copyThing etype

        let arg = Var("arr", atype, false)
        let argExpr = Expr.Var(arg)
        
        let func =
            let m = (getMethod <@ Array.map X X @>).MakeGenericMethod([|etype; etype|])
            Expr.Call(m, [copyfun; argExpr])

        Expr.Lambda(arg, func)

    and genUnionCopier (utype: Type) : Expr = 
        let cases = FSharpType.GetUnionCases utype
        // if - union case - then - copy each field into new case - else - next case

        let arg = Var("x", utype, false)
        let useArg = Expr.Var(arg)

        let genCaseTest case = Expr.UnionCaseTest (useArg, case)
        
        let makeCopyCtor (ci: UnionCaseInfo) = 
            let copiedMembers = [ for field in ci.GetFields() -> genFieldCopy useArg field ]
            Expr.NewUnionCase(ci, copiedMembers)

        let genIf ifCase thenCase elseCase = Expr.IfThenElse(ifCase, thenCase, elseCase)

        let typedFail (str: string) =
            let m = (getMethod <@ failwith str @>).MakeGenericMethod([|utype|])
            Expr.Call(m, [ <@ str @> ])
                                                         
        let nestedIfs = 
            cases
            |> Array.map (fun case -> genIf (genCaseTest case) (makeCopyCtor case))
            |> Array.foldBack (fun iff st -> iff st) <| (typedFail "Unexpected Case in Union")

        Expr.Lambda(arg, nestedIfs)
       
    let toLinq<'I,'O> (expr: Expr<'I -> 'O>) =
        let linq = Microsoft.FSharp.Linq.RuntimeHelpers.LeafExpressionConverter.QuotationToExpression expr
        let call = linq :?> MethodCallExpression
        let lambda  = call.Arguments.[0] :?> LambdaExpression
        Expression.Lambda<Func<'I,'O>>(lambda.Body, lambda.Parameters)

    let genrateRecordDeepCopyFunction<'T> () : ('T -> 'T) = 
        let expr = genRecordCopier typeof<'T> 
        let castExpr : Expr<'T -> 'T> = expr |> Expr.Cast
        let compiledExpr = (castExpr |> toLinq).Compile()
        fun (v : 'T) -> compiledExpr.Invoke(v)
namespace System
namespace System.Reflection
namespace System.ComponentModel
namespace System.Linq
namespace System.Linq.Expressions
namespace Microsoft
namespace Microsoft.FSharp
namespace Microsoft.FSharp.Reflection
namespace Microsoft.FSharp.Quotations
type FSharpType =
  static member GetExceptionFields : exceptionType:Type * ?bindingFlags:BindingFlags -> PropertyInfo []
  static member GetFunctionElements : functionType:Type -> Type * Type
  static member GetRecordFields : recordType:Type * ?bindingFlags:BindingFlags -> PropertyInfo []
  static member GetTupleElements : tupleType:Type -> Type []
  static member GetUnionCases : unionType:Type * ?bindingFlags:BindingFlags -> UnionCaseInfo []
  static member IsExceptionRepresentation : exceptionType:Type * ?bindingFlags:BindingFlags -> bool
  static member IsFunction : typ:Type -> bool
  static member IsModule : typ:Type -> bool
  static member IsRecord : typ:Type * ?bindingFlags:BindingFlags -> bool
  static member IsTuple : typ:Type -> bool
  ...

Full name: Microsoft.FSharp.Reflection.FSharpType
val IsOption : stype:Type -> bool

Full name: Script.FSharpType.IsOption
val stype : Type
type Type =
  inherit MemberInfo
  member Assembly : Assembly
  member AssemblyQualifiedName : string
  member Attributes : TypeAttributes
  member BaseType : Type
  member ContainsGenericParameters : bool
  member DeclaringMethod : MethodBase
  member DeclaringType : Type
  member Equals : o:obj -> bool + 1 overload
  member FindInterfaces : filter:TypeFilter * filterCriteria:obj -> Type[]
  member FindMembers : memberType:MemberTypes * bindingAttr:BindingFlags * filter:MemberFilter * filterCriteria:obj -> MemberInfo[]
  ...

Full name: System.Type
property MemberInfo.Name: string
module RecordCloning

from Script
val application : prms:Expr -> expr:Expr -> Expr

Full name: Script.RecordCloning.application
val prms : Expr
val expr : Expr
Multiple items
type Expr =
  override Equals : obj:obj -> bool
  member GetFreeVars : unit -> seq<Var>
  member Substitute : substitution:(Var -> Expr option) -> Expr
  member ToString : full:bool -> string
  member CustomAttributes : Expr list
  member Type : Type
  static member AddressOf : target:Expr -> Expr
  static member AddressSet : target:Expr * value:Expr -> Expr
  static member Application : functionExpr:Expr * argument:Expr -> Expr
  static member Applications : functionExpr:Expr * arguments:Expr list list -> Expr
  ...

Full name: Microsoft.FSharp.Quotations.Expr

--------------------
type Expr<'T> =
  inherit Expr
  member Raw : Expr

Full name: Microsoft.FSharp.Quotations.Expr<_>
static member Expr.Application : functionExpr:Expr * argument:Expr -> Expr
val coerse : typ:Type -> expr:Expr -> Expr

Full name: Script.RecordCloning.coerse
val typ : Type
static member Expr.Coerce : source:Expr * target:Type -> Expr
val newrec : typ:Type -> args:Expr list -> Expr

Full name: Script.RecordCloning.newrec
val args : Expr list
static member Expr.NewRecord : recordType:Type * elements:Expr list -> Expr
val t : Type
property Type.IsGenericType: bool
Type.GetGenericTypeDefinition() : Type
val typedefof<'T> : Type

Full name: Microsoft.FSharp.Core.Operators.typedefof
Multiple items
module Map

from Microsoft.FSharp.Collections

--------------------
type Map<'Key,'Value (requires comparison)> =
  interface IEnumerable
  interface IComparable
  interface IEnumerable<KeyValuePair<'Key,'Value>>
  interface ICollection<KeyValuePair<'Key,'Value>>
  interface IDictionary<'Key,'Value>
  new : elements:seq<'Key * 'Value> -> Map<'Key,'Value>
  member Add : key:'Key * value:'Value -> Map<'Key,'Value>
  member ContainsKey : key:'Key -> bool
  override Equals : obj -> bool
  member Remove : key:'Key -> Map<'Key,'Value>
  ...

Full name: Microsoft.FSharp.Collections.Map<_,_>

--------------------
new : elements:seq<'Key * 'Value> -> Map<'Key,'Value>
union case Option.Some: Value: 'T -> Option<'T>
union case Option.None: Option<'T>
val copyThing : mtype:Type -> Expr

Full name: Script.RecordCloning.copyThing
val mtype : Type
Multiple items
module FSharpType

from Script

--------------------
type FSharpType =
  static member GetExceptionFields : exceptionType:Type * ?bindingFlags:BindingFlags -> PropertyInfo []
  static member GetFunctionElements : functionType:Type -> Type * Type
  static member GetRecordFields : recordType:Type * ?bindingFlags:BindingFlags -> PropertyInfo []
  static member GetTupleElements : tupleType:Type -> Type []
  static member GetUnionCases : unionType:Type * ?bindingFlags:BindingFlags -> UnionCaseInfo []
  static member IsExceptionRepresentation : exceptionType:Type * ?bindingFlags:BindingFlags -> bool
  static member IsFunction : typ:Type -> bool
  static member IsModule : typ:Type -> bool
  static member IsRecord : typ:Type * ?bindingFlags:BindingFlags -> bool
  static member IsTuple : typ:Type -> bool
  ...

Full name: Microsoft.FSharp.Reflection.FSharpType
static member FSharpType.IsRecord : typ:Type * ?allowAccessToPrivateRepresentation:bool -> bool
static member FSharpType.IsRecord : typ:Type * ?bindingFlags:BindingFlags -> bool
val genRecordCopier : rtype:Type -> Expr

Full name: Script.RecordCloning.genRecordCopier
static member FSharpType.IsUnion : typ:Type * ?allowAccessToPrivateRepresentation:bool -> bool
static member FSharpType.IsUnion : typ:Type * ?bindingFlags:BindingFlags -> bool
val genUnionCopier : utype:Type -> Expr

Full name: Script.RecordCloning.genUnionCopier
property Type.IsValueType: bool
val typeof<'T> : Type

Full name: Microsoft.FSharp.Core.Operators.typeof
Multiple items
type String =
  new : value:char -> string + 7 overloads
  member Chars : int -> char
  member Clone : unit -> obj
  member CompareTo : value:obj -> int + 1 overload
  member Contains : value:string -> bool
  member CopyTo : sourceIndex:int * destination:char[] * destinationIndex:int * count:int -> unit
  member EndsWith : value:string -> bool + 2 overloads
  member Equals : obj:obj -> bool + 2 overloads
  member GetEnumerator : unit -> CharEnumerator
  member GetHashCode : unit -> int
  ...

Full name: System.String

--------------------
String(value: nativeptr<char>) : unit
String(value: nativeptr<sbyte>) : unit
String(value: char []) : unit
String(c: char, count: int) : unit
String(value: nativeptr<char>, startIndex: int, length: int) : unit
String(value: nativeptr<sbyte>, startIndex: int, length: int) : unit
String(value: char [], startIndex: int, length: int) : unit
String(value: nativeptr<sbyte>, startIndex: int, length: int, enc: Text.Encoding) : unit
val getIdFunc : itype:Type -> Expr

Full name: Script.RecordCloning.getIdFunc
property Type.IsArray: bool
val genArrayCopier : atype:Type -> Expr

Full name: Script.RecordCloning.genArrayCopier
active recognizer IsMapType: Type -> Type option

Full name: Script.RecordCloning.( |IsMapType|_| )
Multiple items
type Object =
  new : unit -> obj
  member Equals : obj:obj -> bool
  member GetHashCode : unit -> int
  member GetType : unit -> Type
  member ToString : unit -> string
  static member Equals : objA:obj * objB:obj -> bool
  static member ReferenceEquals : objA:obj * objB:obj -> bool

Full name: System.Object

--------------------
Object() : unit
val failwithf : format:Printf.StringFormat<'T,'Result> -> 'T

Full name: Microsoft.FSharp.Core.ExtraTopLevelOperators.failwithf
Type.ToString() : string
val X : 'T

Full name: Script.RecordCloning.X
module Unchecked

from Microsoft.FSharp.Core.Operators
val defaultof<'T> : 'T

Full name: Microsoft.FSharp.Core.Operators.Unchecked.defaultof
val getMethod : _arg1:Expr -> MethodInfo

Full name: Script.RecordCloning.getMethod
module Patterns

from Microsoft.FSharp.Quotations
active recognizer Call: Expr -> (Expr option * MethodInfo * Expr list) option

Full name: Microsoft.FSharp.Quotations.Patterns.( |Call|_| )
val m : MethodInfo
property MethodBase.IsGenericMethod: bool
MethodInfo.GetGenericMethodDefinition() : MethodInfo
val failwith : message:string -> 'T

Full name: Microsoft.FSharp.Core.Operators.failwith
val itype : Type
val arg : Var
Multiple items
type Var =
  interface IComparable
  new : name:string * typ:Type * ?isMutable:bool -> Var
  member IsMutable : bool
  member Name : string
  member Type : Type
  static member Global : name:string * typ:Type -> Var

Full name: Microsoft.FSharp.Quotations.Var

--------------------
new : name:string * typ:Type * ?isMutable:bool -> Var
val argExpr : Expr
static member Expr.Var : variable:Var -> Expr
val func : Expr
val id : x:'T -> 'T

Full name: Microsoft.FSharp.Core.Operators.id
static member Expr.Call : methodInfo:MethodInfo * arguments:Expr list -> Expr
static member Expr.Call : obj:Expr * methodInfo:MethodInfo * arguments:Expr list -> Expr
static member Expr.Lambda : parameter:Var * body:Expr -> Expr
val rtype : Type
val newrec : Expr
static member FSharpType.GetRecordFields : recordType:Type * ?allowAccessToPrivateRepresentation:bool -> PropertyInfo []
static member FSharpType.GetRecordFields : recordType:Type * ?bindingFlags:BindingFlags -> PropertyInfo []
type Array =
  member Clone : unit -> obj
  member CopyTo : array:Array * index:int -> unit + 1 overload
  member GetEnumerator : unit -> IEnumerator
  member GetLength : dimension:int -> int
  member GetLongLength : dimension:int -> int64
  member GetLowerBound : dimension:int -> int
  member GetUpperBound : dimension:int -> int
  member GetValue : [<ParamArray>] indices:int[] -> obj + 7 overloads
  member Initialize : unit -> unit
  member IsFixedSize : bool
  ...

Full name: System.Array
val toList : array:'T [] -> 'T list

Full name: Microsoft.FSharp.Collections.Array.toList
Multiple items
module List

from Microsoft.FSharp.Collections

--------------------
type List<'T> =
  | ( [] )
  | ( :: ) of Head: 'T * Tail: 'T list
  interface IEnumerable
  interface IEnumerable<'T>
  member Head : 'T
  member IsEmpty : bool
  member Item : index:int -> 'T with get
  member Length : int
  member Tail : 'T list
  static member Cons : head:'T * tail:'T list -> 'T list
  static member Empty : 'T list

Full name: Microsoft.FSharp.Collections.List<_>
val map : mapping:('T -> 'U) -> list:'T list -> 'U list

Full name: Microsoft.FSharp.Collections.List.map
val field : PropertyInfo
val genFieldCopy : argExpr:Expr -> field:PropertyInfo -> Expr

Full name: Script.RecordCloning.genFieldCopy
type PropertyInfo =
  inherit MemberInfo
  member Attributes : PropertyAttributes
  member CanRead : bool
  member CanWrite : bool
  member Equals : obj:obj -> bool
  member GetAccessors : unit -> MethodInfo[] + 1 overload
  member GetConstantValue : unit -> obj
  member GetGetMethod : unit -> MethodInfo + 1 overload
  member GetHashCode : unit -> int
  member GetIndexParameters : unit -> ParameterInfo[]
  member GetOptionalCustomModifiers : unit -> Type[]
  ...

Full name: System.Reflection.PropertyInfo
val pval : Expr
static member Expr.PropertyGet : property:PropertyInfo * ?indexerArgs:Expr list -> Expr
static member Expr.PropertyGet : obj:Expr * property:PropertyInfo * ?indexerArgs:Expr list -> Expr
property PropertyInfo.PropertyType: Type
val atype : Type
val etype : Type
Type.GetElementType() : Type
val copyfun : Expr
val map : mapping:('T -> 'U) -> array:'T [] -> 'U []

Full name: Microsoft.FSharp.Collections.Array.map
val utype : Type
val cases : UnionCaseInfo []
static member FSharpType.GetUnionCases : unionType:Type * ?allowAccessToPrivateRepresentation:bool -> UnionCaseInfo []
static member FSharpType.GetUnionCases : unionType:Type * ?bindingFlags:BindingFlags -> UnionCaseInfo []
val useArg : Expr
val genCaseTest : (UnionCaseInfo -> Expr)
val case : UnionCaseInfo
static member Expr.UnionCaseTest : source:Expr * unionCase:UnionCaseInfo -> Expr
val makeCopyCtor : (UnionCaseInfo -> Expr)
val ci : UnionCaseInfo
type UnionCaseInfo
member GetCustomAttributes : unit -> obj []
member GetCustomAttributes : attributeType:Type -> obj []
member GetCustomAttributesData : unit -> IList<CustomAttributeData>
member GetFields : unit -> PropertyInfo []
member DeclaringType : Type
member Name : string
member Tag : int

Full name: Microsoft.FSharp.Reflection.UnionCaseInfo
val copiedMembers : Expr list
member UnionCaseInfo.GetFields : unit -> PropertyInfo []
static member Expr.NewUnionCase : unionCase:UnionCaseInfo * arguments:Expr list -> Expr
val genIf : (Expr -> Expr -> Expr -> Expr)
val ifCase : Expr
val thenCase : Expr
val elseCase : Expr
static member Expr.IfThenElse : guard:Expr * thenExpr:Expr * elseExpr:Expr -> Expr
val typedFail : (string -> Expr)
val str : string
Multiple items
val string : value:'T -> string

Full name: Microsoft.FSharp.Core.Operators.string

--------------------
type string = String

Full name: Microsoft.FSharp.Core.string
val nestedIfs : Expr
val foldBack : folder:('T -> 'State -> 'State) -> array:'T [] -> state:'State -> 'State

Full name: Microsoft.FSharp.Collections.Array.foldBack
val iff : (Expr -> Expr)
val st : Expr
val toLinq : expr:Expr<('I -> 'O)> -> Expression<Func<'I,'O>>

Full name: Script.RecordCloning.toLinq
val expr : Expr<('I -> 'O)>
val linq : Expression
namespace Microsoft.FSharp.Linq
namespace Microsoft.FSharp.Linq.RuntimeHelpers
module LeafExpressionConverter

from Microsoft.FSharp.Linq.RuntimeHelpers
val QuotationToExpression : Expr -> Expression

Full name: Microsoft.FSharp.Linq.RuntimeHelpers.LeafExpressionConverter.QuotationToExpression
val call : MethodCallExpression
type MethodCallExpression =
  inherit Expression
  member Arguments : ReadOnlyCollection<Expression>
  member Method : MethodInfo
  member NodeType : ExpressionType
  member Object : Expression
  member Type : Type
  member Update : object:Expression * arguments:IEnumerable<Expression> -> MethodCallExpression

Full name: System.Linq.Expressions.MethodCallExpression
val lambda : LambdaExpression
property MethodCallExpression.Arguments: Collections.ObjectModel.ReadOnlyCollection<Expression>
type LambdaExpression =
  inherit Expression
  member Body : Expression
  member Compile : unit -> Delegate + 1 overload
  member CompileToMethod : method:MethodBuilder -> unit + 1 overload
  member Name : string
  member NodeType : ExpressionType
  member Parameters : ReadOnlyCollection<ParameterExpression>
  member ReturnType : Type
  member TailCall : bool
  member Type : Type

Full name: System.Linq.Expressions.LambdaExpression
Multiple items
type Expression =
  member CanReduce : bool
  member NodeType : ExpressionType
  member Reduce : unit -> Expression
  member ReduceAndCheck : unit -> Expression
  member ReduceExtensions : unit -> Expression
  member ToString : unit -> string
  member Type : Type
  static member Add : left:Expression * right:Expression -> BinaryExpression + 1 overload
  static member AddAssign : left:Expression * right:Expression -> BinaryExpression + 2 overloads
  static member AddAssignChecked : left:Expression * right:Expression -> BinaryExpression + 2 overloads
  ...

Full name: System.Linq.Expressions.Expression

--------------------
type Expression<'TDelegate> =
  inherit LambdaExpression
  member Compile : unit -> 'TDelegate + 1 overload
  member Update : body:Expression * parameters:IEnumerable<ParameterExpression> -> Expression<'TDelegate>

Full name: System.Linq.Expressions.Expression<_>
Expression.Lambda(body: Expression, parameters: Collections.Generic.IEnumerable<ParameterExpression>) : LambdaExpression
   (+0 other overloads)
Expression.Lambda(body: Expression, [<ParamArray>] parameters: ParameterExpression []) : LambdaExpression
   (+0 other overloads)
Expression.Lambda<'TDelegate>(body: Expression, parameters: Collections.Generic.IEnumerable<ParameterExpression>) : Expression<'TDelegate>
   (+0 other overloads)
Expression.Lambda<'TDelegate>(body: Expression, [<ParamArray>] parameters: ParameterExpression []) : Expression<'TDelegate>
   (+0 other overloads)
Expression.Lambda(body: Expression, name: string, parameters: Collections.Generic.IEnumerable<ParameterExpression>) : LambdaExpression
   (+0 other overloads)
Expression.Lambda(delegateType: Type, body: Expression, parameters: Collections.Generic.IEnumerable<ParameterExpression>) : LambdaExpression
   (+0 other overloads)
Expression.Lambda(delegateType: Type, body: Expression, [<ParamArray>] parameters: ParameterExpression []) : LambdaExpression
   (+0 other overloads)
Expression.Lambda(body: Expression, tailCall: bool, parameters: Collections.Generic.IEnumerable<ParameterExpression>) : LambdaExpression
   (+0 other overloads)
Expression.Lambda(body: Expression, tailCall: bool, [<ParamArray>] parameters: ParameterExpression []) : LambdaExpression
   (+0 other overloads)
Expression.Lambda<'TDelegate>(body: Expression, name: string, parameters: Collections.Generic.IEnumerable<ParameterExpression>) : Expression<'TDelegate>
   (+0 other overloads)
Multiple items
type Func<'TResult> =
  delegate of unit -> 'TResult

Full name: System.Func<_>

--------------------
type Func<'T,'TResult> =
  delegate of 'T -> 'TResult

Full name: System.Func<_,_>

--------------------
type Func<'T1,'T2,'TResult> =
  delegate of 'T1 * 'T2 -> 'TResult

Full name: System.Func<_,_,_>

--------------------
type Func<'T1,'T2,'T3,'TResult> =
  delegate of 'T1 * 'T2 * 'T3 -> 'TResult

Full name: System.Func<_,_,_,_>

--------------------
type Func<'T1,'T2,'T3,'T4,'TResult> =
  delegate of 'T1 * 'T2 * 'T3 * 'T4 -> 'TResult

Full name: System.Func<_,_,_,_,_>

--------------------
type Func<'T1,'T2,'T3,'T4,'T5,'TResult> =
  delegate of 'T1 * 'T2 * 'T3 * 'T4 * 'T5 -> 'TResult

Full name: System.Func<_,_,_,_,_,_>

--------------------
type Func<'T1,'T2,'T3,'T4,'T5,'T6,'TResult> =
  delegate of 'T1 * 'T2 * 'T3 * 'T4 * 'T5 * 'T6 -> 'TResult

Full name: System.Func<_,_,_,_,_,_,_>

--------------------
type Func<'T1,'T2,'T3,'T4,'T5,'T6,'T7,'TResult> =
  delegate of 'T1 * 'T2 * 'T3 * 'T4 * 'T5 * 'T6 * 'T7 -> 'TResult

Full name: System.Func<_,_,_,_,_,_,_,_>

--------------------
type Func<'T1,'T2,'T3,'T4,'T5,'T6,'T7,'T8,'TResult> =
  delegate of 'T1 * 'T2 * 'T3 * 'T4 * 'T5 * 'T6 * 'T7 * 'T8 -> 'TResult

Full name: System.Func<_,_,_,_,_,_,_,_,_>

--------------------
type Func<'T1,'T2,'T3,'T4,'T5,'T6,'T7,'T8,'T9,'TResult> =
  delegate of 'T1 * 'T2 * 'T3 * 'T4 * 'T5 * 'T6 * 'T7 * 'T8 * 'T9 -> 'TResult

Full name: System.Func<_,_,_,_,_,_,_,_,_,_>

--------------------
type Func<'T1,'T2,'T3,'T4,'T5,'T6,'T7,'T8,'T9,'T10,'TResult> =
  delegate of 'T1 * 'T2 * 'T3 * 'T4 * 'T5 * 'T6 * 'T7 * 'T8 * 'T9 * 'T10 -> 'TResult

Full name: System.Func<_,_,_,_,_,_,_,_,_,_,_>

--------------------
type Func<'T1,'T2,'T3,'T4,'T5,'T6,'T7,'T8,'T9,'T10,'T11,'TResult> =
  delegate of 'T1 * 'T2 * 'T3 * 'T4 * 'T5 * 'T6 * 'T7 * 'T8 * 'T9 * 'T10 * 'T11 -> 'TResult

Full name: System.Func<_,_,_,_,_,_,_,_,_,_,_,_>

--------------------
type Func<'T1,'T2,'T3,'T4,'T5,'T6,'T7,'T8,'T9,'T10,'T11,'T12,'TResult> =
  delegate of 'T1 * 'T2 * 'T3 * 'T4 * 'T5 * 'T6 * 'T7 * 'T8 * 'T9 * 'T10 * 'T11 * 'T12 -> 'TResult

Full name: System.Func<_,_,_,_,_,_,_,_,_,_,_,_,_>

--------------------
type Func<'T1,'T2,'T3,'T4,'T5,'T6,'T7,'T8,'T9,'T10,'T11,'T12,'T13,'TResult> =
  delegate of 'T1 * 'T2 * 'T3 * 'T4 * 'T5 * 'T6 * 'T7 * 'T8 * 'T9 * 'T10 * 'T11 * 'T12 * 'T13 -> 'TResult

Full name: System.Func<_,_,_,_,_,_,_,_,_,_,_,_,_,_>

--------------------
type Func<'T1,'T2,'T3,'T4,'T5,'T6,'T7,'T8,'T9,'T10,'T11,'T12,'T13,'T14,'TResult> =
  delegate of 'T1 * 'T2 * 'T3 * 'T4 * 'T5 * 'T6 * 'T7 * 'T8 * 'T9 * 'T10 * 'T11 * 'T12 * 'T13 * 'T14 -> 'TResult

Full name: System.Func<_,_,_,_,_,_,_,_,_,_,_,_,_,_,_>

--------------------
type Func<'T1,'T2,'T3,'T4,'T5,'T6,'T7,'T8,'T9,'T10,'T11,'T12,'T13,'T14,'T15,'TResult> =
  delegate of 'T1 * 'T2 * 'T3 * 'T4 * 'T5 * 'T6 * 'T7 * 'T8 * 'T9 * 'T10 * 'T11 * 'T12 * 'T13 * 'T14 * 'T15 -> 'TResult

Full name: System.Func<_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_>

--------------------
type Func<'T1,'T2,'T3,'T4,'T5,'T6,'T7,'T8,'T9,'T10,'T11,'T12,'T13,'T14,'T15,'T16,'TResult> =
  delegate of 'T1 * 'T2 * 'T3 * 'T4 * 'T5 * 'T6 * 'T7 * 'T8 * 'T9 * 'T10 * 'T11 * 'T12 * 'T13 * 'T14 * 'T15 * 'T16 -> 'TResult

Full name: System.Func<_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_>
property LambdaExpression.Body: Expression
property LambdaExpression.Parameters: Collections.ObjectModel.ReadOnlyCollection<ParameterExpression>
val genrateRecordDeepCopyFunction : unit -> ('T -> 'T)

Full name: Script.RecordCloning.genrateRecordDeepCopyFunction
val castExpr : Expr<('T -> 'T)>
static member Expr.Cast : source:Expr -> Expr<'T>
val compiledExpr : Func<'T,'T>
val v : 'T
Func.Invoke(arg: 'T) : 'T
Raw view Test code New version

More information

Link:http://fssnip.net/n1
Posted:9 years ago
Author:Rick Minerich
Tags: expr , quotations