3 people like it.
Like the snippet!
Normalization by Evaluation
Optimizing F# quotations by applying Normalization-by-Evaluation
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:
111:
112:
113:
114:
115:
116:
117:
118:
119:
120:
121:
122:
123:
124:
125:
126:
127:
128:
129:
130:
131:
132:
133:
134:
135:
136:
137:
138:
139:
140:
141:
142:
143:
144:
145:
146:
147:
148:
149:
150:
151:
152:
153:
154:
155:
156:
157:
158:
159:
160:
161:
162:
163:
164:
165:
166:
167:
168:
169:
170:
171:
172:
173:
174:
175:
176:
177:
178:
179:
180:
181:
182:
|
open System
open System.Reflection
open FSharp.Reflection
open FSharp.Quotations
open FSharp.Quotations.Patterns
open FSharp.Quotations.DerivedPatterns
open FSharp.Quotations.ExprShape
// Semantic interpretation of quotation trees
type Sem =
| VAR of Var * value:Sem option
| LIT of obj * Type
| LAM of Var * (Sem -> Sem)
| LET of Var * Sem * Sem
| TUPLE of Type * Sem list
| RECORD of Type * Sem list
| UNION of UnionCaseInfo * Sem list
// Standard arithmetic operator expression
| OP of MethodInfo * Sem list
// Embeds arbitrary syntactic trees
| SYN of isPureNode:bool * shape:obj * Sem list
/// determines if expression is guaranteed to evaluate without side-effects
let rec isPure (s : Sem) =
match s with
| VAR (v,_) -> not v.IsMutable
| LIT _ | LAM _ -> true
| SYN(isPureNode = isPure) -> isPure
| LET(_,b,k) -> isPure b && isPure k
| TUPLE (_,fs) | RECORD (_,fs) | UNION(_,fs) | OP(_,fs) -> fs |> List.forall isPure
type Environment = Map<Var, Sem>
/// Maps syntactic trees to semantic expressions; apply optimizations as required
let rec meaning (env : Environment) (expr : Expr) : Sem =
let mkLit (x : 'T) = LIT(x, typeof<'T>)
let (|Deref|) s =
match s with
| VAR(_, Some s) -> s
| _ -> s
// trivial semantic mapping; use as fallback when no other optimizations can be applied
let fallback (env : Environment) (expr : Expr) =
match expr with
| ShapeVar v ->
match env.TryFind v with
| Some (LIT _ | VAR _ as s) -> s
| sopt -> VAR(v, sopt)
| ShapeLambda(v, body) -> LAM(v, fun s -> meaning (env.Add(v, s)) body)
| ShapeCombination(shape, args) ->
let sargs = args |> List.map (meaning env)
let isPureNode =
match expr with
| IfThenElse _
| TupleGet _
| TypeTest _
| UnionCaseTest _
| LetRecursive _
| QuoteRaw _
| QuoteTyped _ -> true
| PropertyGet(Some e, _, []) when
FSharpType.IsRecord(e.Type, true) ||
FSharpType.IsUnion(e.Type, true) ||
FSharpType.IsTuple(e.Type) -> true
| _ -> false
SYN(isPureNode, shape, sargs)
match expr with
| Value(o, t) -> LIT(o, t)
| Application(f, g) ->
match meaning env f with
| Deref (LAM (v, lam)) ->
match meaning env g with
// (λ x. M) N ~> M[N/x]
| LIT _ | VAR _ | LAM _ as s -> lam s
// (λ x. M) N ~> let x = N in M
| s -> LET(v, s, lam (VAR(v, Some s)))
| _ -> fallback env expr
| Let(v, binding, body) when not v.IsMutable ->
let (Deref s) = meaning env binding
match meaning (env.Add(v, s)) body with
| VAR(x, _) when x = v -> s // let x = N in x ~> N
| sk -> LET(v, s, sk)
| IfThenElse(cond, ifExpr, elseExpr) ->
match meaning env cond with
| Deref (LIT(:? bool as ccond, _)) ->
// branch elimination
let branch = if ccond then ifExpr else elseExpr
meaning env branch
| _ -> fallback env expr
| Sequential(left, right) ->
match meaning env left with
| ls when isPure ls ->
match meaning env right with
| rs when isPure rs -> mkLit ()
| rs -> rs
| _ -> fallback env expr
// Tuple introduction & elimination [https://github.com/dotnet/fsharp/issues/7914]
| NewTuple ts when not expr.Type.IsValueType -> TUPLE(expr.Type, ts |> List.map (meaning env))
| TupleGet(tuple, i) ->
match meaning env tuple with
| Deref (TUPLE (_, ts)) -> ts.[i]
| _ -> fallback env expr
// Record introduction & elimination
| NewRecord(t, fs) -> RECORD(t, fs |> List.map (meaning env))
| PropertyGet(Some e, prop, []) ->
match meaning env e with
| Deref (RECORD(t,fs)) ->
match FSharpType.GetRecordFields(t, true) |> Array.tryFindIndex(fun p -> prop = p) with
| Some i -> fs.[i]
| None -> fallback env expr
| Deref (UNION(uci, fs)) ->
match uci.GetFields() |> Array.tryFindIndex(fun p -> prop = p) with
| Some i -> fs.[i]
| None -> fallback env expr
| _ -> fallback env expr
// Union introduction & elimination
| NewUnionCase(uci, fs) -> UNION(uci, fs |> List.map (meaning env))
| UnionCaseTest(e, uci) ->
match meaning env e with
| Deref (UNION(uci', _)) -> mkLit(uci = uci')
| _ -> fallback env expr
| SpecificCall <@ (|>) @> (None, _, [value; func])
| SpecificCall <@ (<|) @> (None, _, [func; value]) -> meaning env (Expr.Application(func, value))
| SpecificCall <@ fst @> (None, _, [t]) -> meaning env (Expr.TupleGet(t, 0))
| SpecificCall <@ snd @> (None, _, [t]) -> meaning env (Expr.TupleGet(t, 1))
| SpecificCall <@ ignore @> (None, _, [value]) -> meaning env (Expr.Sequential(value, Expr.Value(())))
| Call(None, mi, args) when mi.DeclaringType.FullName = "Microsoft.FSharp.Core.Operators" && mi.Name.StartsWith "op_" ->
let sargs = args |> List.map (meaning env)
let literals = sargs |> Seq.choose (function (Deref (LIT(o,_))) -> Some o | _ -> None) |> Seq.toArray
if literals.Length = sargs.Length then
// evaluate constant expressions
try LIT(mi.Invoke(null, literals), expr.Type)
with :? TargetException as e when (e.InnerException :? NotSupportedException) ->
// "Dynamic invocation of operator is not supported"
OP(mi, sargs)
else
OP(mi, sargs)
| _ -> fallback env expr
/// Maps semantic expressions back to a syntactic representation
let reify (s : Sem) : Expr =
let rec aux (refdVars : Set<Var>) s =
let foldMap refdVars (ss : Sem list) =
let mutable refdVars = refdVars
let es = ss |> List.map (fun s -> let r,e = aux refdVars s in refdVars <- r; e)
refdVars, es
match s with
| VAR (v, _) -> refdVars.Add v, Expr.Var v
| LIT (o, t) -> refdVars, Expr.Value(o, t)
| LAM (v, lam) -> refdVars, Expr.Lambda(v, lam (VAR (v, None)) |> aux refdVars |> snd)
| LET (v, b, k) ->
let kvars, ek = aux refdVars k
if isPure b && not (kvars.Contains v) then
kvars, ek
else
let bvars, eb = aux refdVars b
Set.union kvars bvars, Expr.Let(v, eb, ek)
| TUPLE (_,fs) -> let refdVars,es = foldMap refdVars fs in refdVars, Expr.NewTuple(es)
| RECORD (t, fs) -> let refdVars,es = foldMap refdVars fs in refdVars, Expr.NewRecord(t, es)
| UNION (uci, fs) -> let refdVars,es = foldMap refdVars fs in refdVars, Expr.NewUnionCase(uci, es)
| OP(mI, args) -> let refdVars,es = foldMap refdVars args in refdVars, Expr.Call(mI, es)
| SYN(_, shape, sparams) -> let refdVars,es = foldMap refdVars sparams in refdVars, RebuildShapeCombination(shape, es)
aux Set.empty s |> snd
/// Apply normalization-by-evaluation to quotation tree
let nbe (expr : Expr<'a>) : Expr<'a> = expr |> meaning Map.empty |> reify |> Expr.Cast
|
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:
|
let nbe_decompile expr = expr |> nbe |> Swensen.Unquote.Operators.decompile
nbe_decompile
<@
let f x =
match x with
| Some i -> i > 0
| None -> false
f (Some 42), f None
@>
// (true, false)
nbe_decompile
<@
fun () ->
let mutable y = 0
let f x = x + 2
y <- f 2
y + 1
@>
// fun () -> let mutable y = 0 in y <- 4; y + 1
nbe_decompile
<@
fun z ->
let f x =
if x > 0 then Console.WriteLine "Positive"
elif x = 0 then Console.WriteLine "Zero"
else Console.WriteLine "Negative"
f -1; f 0; f z
@>
// fun z ->
// Console.WriteLine("Negative")
// Console.WriteLine("Zero")
// if z > 0 then Console.WriteLine("Positive")
// else (if z = 0 then Console.WriteLine("Zero")
// else Console.WriteLine("Negative"))
|
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:
|
// Nessos streams: http://trelford.com/blog/post/SeqVsStream.aspx
type Stream<'T> = ('T -> unit) -> unit
nbe_decompile
<@
let ofArray (xs : int []) =
fun k -> for x in xs do k x
let map : (int -> int) -> Stream<int> -> Stream<int> =
fun f ts k -> ts (fun t -> k (f t))
let filter : (int -> bool) -> Stream<int> -> Stream<int> =
fun f ts k -> ts (fun t -> if (f t) then k t)
let iter : (int -> unit) -> Stream<int> -> unit =
fun f ts -> ts f
fun xs ->
ofArray xs
|> filter (fun i -> i > 0)
|> filter (fun i -> i % 2 = 0)
|> map (fun i -> i * i)
|> map (fun i -> i + i)
|> iter (fun i -> printfn "%d" i)
@>
//fun (xs : int []) ->
// for x in xs do
// if x > 0 then
// if x % 2 = 0 then
// let t = x * x
// let i = t + t
// printfn "%d" i
|
namespace System
namespace System.Reflection
namespace Microsoft.FSharp
namespace Microsoft.FSharp.Reflection
namespace Microsoft.FSharp.Quotations
module Patterns
from Microsoft.FSharp.Quotations
module DerivedPatterns
from Microsoft.FSharp.Quotations
module ExprShape
from Microsoft.FSharp.Quotations
type Sem =
| VAR of Var * value: Sem option
| LIT of obj * Type
| LAM of Var * (Sem -> Sem)
| LET of Var * Sem * Sem
| TUPLE of Type * Sem list
| RECORD of Type * Sem list
| UNION of UnionCaseInfo * Sem list
| OP of MethodInfo * Sem list
| SYN of isPureNode: bool * shape: obj * Sem list
Full name: Script.Sem
union case Sem.VAR: Var * value: Sem option -> Sem
Multiple items
active recognizer Var: Expr -> Var option
Full name: Microsoft.FSharp.Quotations.Patterns.( |Var|_| )
--------------------
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
type 'T option = Option<'T>
Full name: Microsoft.FSharp.Core.option<_>
union case Sem.LIT: obj * Type -> Sem
type obj = Object
Full name: Microsoft.FSharp.Core.obj
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
union case Sem.LAM: Var * (Sem -> Sem) -> Sem
union case Sem.LET: Var * Sem * Sem -> Sem
union case Sem.TUPLE: Type * Sem list -> Sem
type 'T list = List<'T>
Full name: Microsoft.FSharp.Collections.list<_>
union case Sem.RECORD: Type * Sem list -> Sem
union case Sem.UNION: UnionCaseInfo * Sem list -> Sem
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
union case Sem.OP: MethodInfo * Sem list -> Sem
type MethodInfo =
inherit MethodBase
member Equals : obj:obj -> bool
member GetBaseDefinition : unit -> MethodInfo
member GetGenericArguments : unit -> Type[]
member GetGenericMethodDefinition : unit -> MethodInfo
member GetHashCode : unit -> int
member MakeGenericMethod : [<ParamArray>] typeArguments:Type[] -> MethodInfo
member MemberType : MemberTypes
member ReturnParameter : ParameterInfo
member ReturnType : Type
member ReturnTypeCustomAttributes : ICustomAttributeProvider
Full name: System.Reflection.MethodInfo
union case Sem.SYN: isPureNode: bool * shape: obj * Sem list -> Sem
type bool = Boolean
Full name: Microsoft.FSharp.Core.bool
val isPure : s:Sem -> bool
Full name: Script.isPure
determines if expression is guaranteed to evaluate without side-effects
val s : Sem
val v : Var
val not : value:bool -> bool
Full name: Microsoft.FSharp.Core.Operators.not
property Var.IsMutable: bool
val isPure : bool
val b : Sem
val k : Sem
val fs : Sem list
Multiple items
module List
from Microsoft.FSharp.Collections
--------------------
type List<'T> =
| ( [] )
| ( :: ) of Head: 'T * Tail: 'T list
interface IEnumerable
interface IEnumerable<'T>
member GetSlice : startIndex:int option * endIndex:int option -> 'T list
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 forall : predicate:('T -> bool) -> list:'T list -> bool
Full name: Microsoft.FSharp.Collections.List.forall
type Environment = Map<Var,Sem>
Full name: Script.Environment
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>
val meaning : env:Environment -> expr:Expr -> Sem
Full name: Script.meaning
Maps syntactic trees to semantic expressions; apply optimizations as required
val env : Environment
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<_>
val mkLit : ('T -> Sem)
val x : 'T
val typeof<'T> : Type
Full name: Microsoft.FSharp.Core.Operators.typeof
union case Option.Some: Value: 'T -> Option<'T>
val fallback : (Environment -> Expr -> Sem)
active recognizer ShapeVar: Expr -> Choice<Var,(Var * Expr),(obj * Expr list)>
Full name: Microsoft.FSharp.Quotations.ExprShape.( |ShapeVar|ShapeLambda|ShapeCombination| )
member Map.TryFind : key:'Key -> 'Value option
val sopt : Sem option
active recognizer ShapeLambda: Expr -> Choice<Var,(Var * Expr),(obj * Expr list)>
Full name: Microsoft.FSharp.Quotations.ExprShape.( |ShapeVar|ShapeLambda|ShapeCombination| )
val body : Expr
member Map.Add : key:'Key * value:'Value -> Map<'Key,'Value>
active recognizer ShapeCombination: Expr -> Choice<Var,(Var * Expr),(obj * Expr list)>
Full name: Microsoft.FSharp.Quotations.ExprShape.( |ShapeVar|ShapeLambda|ShapeCombination| )
val shape : obj
val args : Expr list
val sargs : Sem list
val map : mapping:('T -> 'U) -> list:'T list -> 'U list
Full name: Microsoft.FSharp.Collections.List.map
val isPureNode : bool
active recognizer IfThenElse: Expr -> (Expr * Expr * Expr) option
Full name: Microsoft.FSharp.Quotations.Patterns.( |IfThenElse|_| )
active recognizer TupleGet: Expr -> (Expr * int) option
Full name: Microsoft.FSharp.Quotations.Patterns.( |TupleGet|_| )
active recognizer TypeTest: Expr -> (Expr * Type) option
Full name: Microsoft.FSharp.Quotations.Patterns.( |TypeTest|_| )
active recognizer UnionCaseTest: Expr -> (Expr * UnionCaseInfo) option
Full name: Microsoft.FSharp.Quotations.Patterns.( |UnionCaseTest|_| )
active recognizer LetRecursive: Expr -> ((Var * Expr) list * Expr) option
Full name: Microsoft.FSharp.Quotations.Patterns.( |LetRecursive|_| )
active recognizer QuoteRaw: Expr -> Expr option
Full name: Microsoft.FSharp.Quotations.Patterns.( |QuoteRaw|_| )
active recognizer QuoteTyped: Expr -> Expr option
Full name: Microsoft.FSharp.Quotations.Patterns.( |QuoteTyped|_| )
active recognizer PropertyGet: Expr -> (Expr option * PropertyInfo * Expr list) option
Full name: Microsoft.FSharp.Quotations.Patterns.( |PropertyGet|_| )
val e : Expr
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
property Expr.Type: Type
static member FSharpType.IsUnion : typ:Type * ?allowAccessToPrivateRepresentation:bool -> bool
static member FSharpType.IsUnion : typ:Type * ?bindingFlags:BindingFlags -> bool
static member FSharpType.IsTuple : typ:Type -> bool
active recognizer Value: Expr -> (obj * Type) option
Full name: Microsoft.FSharp.Quotations.Patterns.( |Value|_| )
val o : obj
val t : Type
active recognizer Application: Expr -> (Expr * Expr) option
Full name: Microsoft.FSharp.Quotations.Patterns.( |Application|_| )
val f : Expr
val g : Expr
active recognizer Deref: Sem -> Sem
val lam : (Sem -> Sem)
active recognizer Let: Expr -> (Var * Expr * Expr) option
Full name: Microsoft.FSharp.Quotations.Patterns.( |Let|_| )
val binding : Expr
val x : Var
val sk : Sem
val cond : Expr
val ifExpr : Expr
val elseExpr : Expr
val ccond : bool
val branch : Expr
active recognizer Sequential: Expr -> (Expr * Expr) option
Full name: Microsoft.FSharp.Quotations.Patterns.( |Sequential|_| )
val left : Expr
val right : Expr
val ls : Sem
val rs : Sem
active recognizer NewTuple: Expr -> Expr list option
Full name: Microsoft.FSharp.Quotations.Patterns.( |NewTuple|_| )
val ts : Expr list
property Type.IsValueType: bool
val tuple : Expr
val i : int
val ts : Sem list
active recognizer NewRecord: Expr -> (Type * Expr list) option
Full name: Microsoft.FSharp.Quotations.Patterns.( |NewRecord|_| )
val fs : Expr list
val prop : PropertyInfo
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 tryFindIndex : predicate:('T -> bool) -> array:'T [] -> int option
Full name: Microsoft.FSharp.Collections.Array.tryFindIndex
val p : PropertyInfo
union case Option.None: Option<'T>
val uci : UnionCaseInfo
member UnionCaseInfo.GetFields : unit -> PropertyInfo []
active recognizer NewUnionCase: Expr -> (UnionCaseInfo * Expr list) option
Full name: Microsoft.FSharp.Quotations.Patterns.( |NewUnionCase|_| )
val uci' : UnionCaseInfo
active recognizer SpecificCall: Expr -> Expr -> (Expr option * Type list * Expr list) option
Full name: Microsoft.FSharp.Quotations.DerivedPatterns.( |SpecificCall|_| )
val value : Expr
val func : Expr
static member Expr.Application : functionExpr:Expr * argument:Expr -> Expr
val fst : tuple:('T1 * 'T2) -> 'T1
Full name: Microsoft.FSharp.Core.Operators.fst
val t : Expr
static member Expr.TupleGet : tuple:Expr * index:int -> Expr
val snd : tuple:('T1 * 'T2) -> 'T2
Full name: Microsoft.FSharp.Core.Operators.snd
val ignore : value:'T -> unit
Full name: Microsoft.FSharp.Core.Operators.ignore
static member Expr.Sequential : first:Expr * second:Expr -> Expr
static member Expr.Value : value:'T -> Expr
static member Expr.Value : value:obj * expressionType:Type -> Expr
active recognizer Call: Expr -> (Expr option * MethodInfo * Expr list) option
Full name: Microsoft.FSharp.Quotations.Patterns.( |Call|_| )
val mi : MethodInfo
property MemberInfo.DeclaringType: Type
property Type.FullName: string
property MemberInfo.Name: string
String.StartsWith(value: string) : bool
String.StartsWith(value: string, comparisonType: StringComparison) : bool
String.StartsWith(value: string, ignoreCase: bool, culture: Globalization.CultureInfo) : bool
val literals : obj []
module Seq
from Microsoft.FSharp.Collections
val choose : chooser:('T -> 'U option) -> source:seq<'T> -> seq<'U>
Full name: Microsoft.FSharp.Collections.Seq.choose
val toArray : source:seq<'T> -> 'T []
Full name: Microsoft.FSharp.Collections.Seq.toArray
property Array.Length: int
property List.Length: int
MethodBase.Invoke(obj: obj, parameters: obj []) : obj
MethodBase.Invoke(obj: obj, invokeAttr: BindingFlags, binder: Binder, parameters: obj [], culture: Globalization.CultureInfo) : obj
Multiple items
type TargetException =
inherit ApplicationException
new : unit -> TargetException + 2 overloads
Full name: System.Reflection.TargetException
--------------------
TargetException() : unit
TargetException(message: string) : unit
TargetException(message: string, inner: exn) : unit
val e : TargetException
property Exception.InnerException: exn
Multiple items
type NotSupportedException =
inherit SystemException
new : unit -> NotSupportedException + 2 overloads
Full name: System.NotSupportedException
--------------------
NotSupportedException() : unit
NotSupportedException(message: string) : unit
NotSupportedException(message: string, innerException: exn) : unit
val reify : s:Sem -> Expr
Full name: Script.reify
Maps semantic expressions back to a syntactic representation
val aux : (Set<Var> -> Sem -> Set<Var> * Expr)
val refdVars : Set<Var>
Multiple items
module Set
from Microsoft.FSharp.Collections
--------------------
type Set<'T (requires comparison)> =
interface IComparable
interface IEnumerable
interface IEnumerable<'T>
interface ICollection<'T>
new : elements:seq<'T> -> Set<'T>
member Add : value:'T -> Set<'T>
member Contains : value:'T -> bool
override Equals : obj -> bool
member IsProperSubsetOf : otherSet:Set<'T> -> bool
member IsProperSupersetOf : otherSet:Set<'T> -> bool
...
Full name: Microsoft.FSharp.Collections.Set<_>
--------------------
new : elements:seq<'T> -> Set<'T>
val foldMap : (Set<Var> -> Sem list -> Set<Var> * Expr list)
val ss : Sem list
val mutable refdVars : Set<Var>
val es : Expr list
val r : Set<Var>
member Set.Add : value:'T -> Set<'T>
static member Expr.Var : variable:Var -> Expr
static member Expr.Lambda : parameter:Var * body:Expr -> Expr
val kvars : Set<Var>
val ek : Expr
member Set.Contains : value:'T -> bool
val bvars : Set<Var>
val eb : Expr
val union : set1:Set<'T> -> set2:Set<'T> -> Set<'T> (requires comparison)
Full name: Microsoft.FSharp.Collections.Set.union
static member Expr.Let : letVariable:Var * letExpr:Expr * body:Expr -> Expr
static member Expr.NewTuple : elements:Expr list -> Expr
static member Expr.NewRecord : recordType:Type * elements:Expr list -> Expr
static member Expr.NewUnionCase : unionCase:UnionCaseInfo * arguments:Expr list -> Expr
val mI : MethodInfo
val args : Sem list
static member Expr.Call : methodInfo:MethodInfo * arguments:Expr list -> Expr
static member Expr.Call : obj:Expr * methodInfo:MethodInfo * arguments:Expr list -> Expr
val sparams : Sem list
val RebuildShapeCombination : shape:obj * arguments:Expr list -> Expr
Full name: Microsoft.FSharp.Quotations.ExprShape.RebuildShapeCombination
val empty<'T (requires comparison)> : Set<'T> (requires comparison)
Full name: Microsoft.FSharp.Collections.Set.empty
val nbe : expr:Expr<'a> -> Expr<'a>
Full name: Script.nbe
Apply normalization-by-evaluation to quotation tree
val expr : Expr<'a>
val empty<'Key,'T (requires comparison)> : Map<'Key,'T> (requires comparison)
Full name: Microsoft.FSharp.Collections.Map.empty
static member Expr.Cast : source:Expr -> Expr<'T>
val nbe_decompile : expr:Expr<'a> -> string
Full name: Script.nbe_decompile
namespace Swensen
namespace Swensen.Unquote
module Operators
from Swensen.Unquote
val decompile : expr:Expr -> string
Full name: Swensen.Unquote.Operators.decompile
val f : (int option -> bool)
val x : int option
val mutable y : int
val f : (int -> int)
val x : int
val z : int
val f : (int -> unit)
type Console =
static member BackgroundColor : ConsoleColor with get, set
static member Beep : unit -> unit + 1 overload
static member BufferHeight : int with get, set
static member BufferWidth : int with get, set
static member CapsLock : bool
static member Clear : unit -> unit
static member CursorLeft : int with get, set
static member CursorSize : int with get, set
static member CursorTop : int with get, set
static member CursorVisible : bool with get, set
...
Full name: System.Console
Console.WriteLine() : unit
(+0 other overloads)
Console.WriteLine(value: string) : unit
(+0 other overloads)
Console.WriteLine(value: obj) : unit
(+0 other overloads)
Console.WriteLine(value: uint64) : unit
(+0 other overloads)
Console.WriteLine(value: int64) : unit
(+0 other overloads)
Console.WriteLine(value: uint32) : unit
(+0 other overloads)
Console.WriteLine(value: int) : unit
(+0 other overloads)
Console.WriteLine(value: float32) : unit
(+0 other overloads)
Console.WriteLine(value: float) : unit
(+0 other overloads)
Console.WriteLine(value: decimal) : unit
(+0 other overloads)
type Stream<'T> = ('T -> unit) -> unit
Full name: Script.Stream<_>
type unit = Unit
Full name: Microsoft.FSharp.Core.unit
val ofArray : (int [] -> (int -> unit) -> unit)
val xs : int []
Multiple items
val int : value:'T -> int (requires member op_Explicit)
Full name: Microsoft.FSharp.Core.Operators.int
--------------------
type int = int32
Full name: Microsoft.FSharp.Core.int
--------------------
type int<'Measure> = int
Full name: Microsoft.FSharp.Core.int<_>
val k : (int -> unit)
val map : ((int -> int) -> Stream<int> -> Stream<int>)
val ts : Stream<int>
val t : int
val filter : ((int -> bool) -> Stream<int> -> Stream<int>)
val f : (int -> bool)
val iter : ((int -> unit) -> Stream<int> -> unit)
val printfn : format:Printf.TextWriterFormat<'T> -> 'T
Full name: Microsoft.FSharp.Core.ExtraTopLevelOperators.printfn
More information