From bc9428affb1cbb0c68e77160e94f7b14e4fc3c8c Mon Sep 17 00:00:00 2001
From: Gusty <1261319+gusty@users.noreply.github.com>
Date: Sun, 11 Oct 2020 12:47:23 +0200
Subject: [PATCH 01/13] Initial implementation

---
 src/FSharpPlus/Control/Monad.fs   |  4 +++-
 src/FSharpPlus/Extensions/Expr.fs | 36 +++++++++++++++++++++++++++++++
 src/FSharpPlus/FSharpPlus.fsproj  |  1 +
 3 files changed, 40 insertions(+), 1 deletion(-)
 create mode 100644 src/FSharpPlus/Extensions/Expr.fs

diff --git a/src/FSharpPlus/Control/Monad.fs b/src/FSharpPlus/Control/Monad.fs
index cfbc24936..ac148e153 100644
--- a/src/FSharpPlus/Control/Monad.fs
+++ b/src/FSharpPlus/Control/Monad.fs
@@ -35,6 +35,8 @@ type Bind =
     static member        (>>=) (source             , k: 'T -> _           ) = Result.bind k source                                          : Result<'U,'E>
     static member        (>>=) (source             , k: 'T -> _           ) = Choice.bind k source                                          : Choice<'U,'E>
 
+    static member        (>>=) (source: Expr<'T>   , f: 'T -> Expr<'U>    ) = Expr.bind f source                                            : Expr<'U>
+
     static member (>>=) (source: Map<'Key,'T>, f: 'T -> Map<'Key,'U>) = Map (seq {
                    for KeyValue(k, v) in source do
                        match Map.tryFind k (f v) with
@@ -158,7 +160,7 @@ type Delay =
     static member        Delay (_mthd: Default2, x: unit-> 'R -> _                                        , _          ) = (fun s -> x () s): 'R -> _
     static member        Delay (_mthd: Delay   , x: unit-> _                                              , _          ) = async.Delay x    : Async<'T>
     static member        Delay (_mthd: Delay   , x: unit-> Lazy<_>                                        , _          ) = lazy (x().Value) : Lazy<'T>
-    
+    static member        Delay (_mthd: Delay   , x: unit-> Expr<_>                                        , _          ) = Expr.bind x (Return.Invoke ()) : Expr<'T>
 
     static member inline Invoke source : 'R =
         let inline call (mthd: ^M, input: unit -> ^I) = ((^M or ^I) : (static member Delay : _*_*_ -> _) mthd, input, Unchecked.defaultof<Delay>)
diff --git a/src/FSharpPlus/Extensions/Expr.fs b/src/FSharpPlus/Extensions/Expr.fs
new file mode 100644
index 000000000..abcb4f149
--- /dev/null
+++ b/src/FSharpPlus/Extensions/Expr.fs
@@ -0,0 +1,36 @@
+namespace FSharpPlus
+
+/// Additional operations on Quotations.Expr
+[<RequireQualifiedAccess>]
+module Expr =
+    
+    open System
+    open Microsoft.FSharp.Quotations
+    open Microsoft.FSharp.Quotations.Patterns
+    open Microsoft.FSharp.Quotations.ExprShape
+
+    let [<Literal>] private fsNamespace = "Microsoft.FSharp.Core"
+
+    let [<Literal>] private opSliceName = "SpliceExpression"
+    let [<Literal>] private opSliceType = "ExtraTopLevelOperators"
+
+    let private fsCoreAs = AppDomain.CurrentDomain.GetAssemblies () |> Seq.find (fun a -> a.GetName().Name = "FSharp.Core")
+    let private miSplice = fsCoreAs.GetType(fsNamespace + "." + opSliceType).GetMethod opSliceName
+        
+    let bind (f: 'T -> Expr<'U>) (x: Expr<'T>) : Expr<'U> =
+        Expr.Coerce (Expr.Call (miSplice.MakeGenericMethod typeof<'U>, [Expr.Application (Expr.Value f, x)]), typeof<'U>)
+        |> Expr.Cast
+
+    let rec runWithUntyped (eval: Expr -> obj) (exp: Expr) s =
+        let m = if isNull s then let x = Reflection.MethodInfo.GetCurrentMethod () in x.DeclaringType.GetMethod x.Name else s
+        let rec subsExpr = function
+            | Call (None, mi, exprLst) 
+                when (mi.Name, mi.DeclaringType.Name, mi.DeclaringType.Namespace) = (opSliceName, opSliceType, fsNamespace)
+                -> Expr.Call (m, [Expr.Value eval; subsExpr exprLst.Head; Expr.Value m])
+            | ShapeVar var                        -> Expr.Var var
+            | ShapeLambda (var, expr)             -> Expr.Lambda (var, subsExpr expr)
+            | ShapeCombination (shpComb, exprLst) -> RebuildShapeCombination (shpComb, List.map subsExpr exprLst)
+        eval (subsExpr exp)
+    
+    /// Executes quoted expression, given a quotation evaluator function.
+    let run (eval: Expr -> obj) (exp: Expr<'T>) : 'T = runWithUntyped eval exp.Raw null :?> 'T
\ No newline at end of file
diff --git a/src/FSharpPlus/FSharpPlus.fsproj b/src/FSharpPlus/FSharpPlus.fsproj
index 8c18fba5f..f6c84522d 100644
--- a/src/FSharpPlus/FSharpPlus.fsproj
+++ b/src/FSharpPlus/FSharpPlus.fsproj
@@ -47,6 +47,7 @@
     <Compile Include="Extensions/Task.fs" />
     <Compile Include="Extensions/Async.fs" />
     <Compile Include="Extensions/Extensions.fs" />
+    <Compile Include="Extensions/Expr.fs" />
     <Compile Include="Extensions/Tuple.fs" />
     <Compile Include="TypeLevel/TypeLevelOperators.fs" />
     <Compile Include="TypeLevel/TypeBool.fs" />

From ad9cdf0070ab90ac1b28f0781e0b500ef3eb0379 Mon Sep 17 00:00:00 2001
From: Gusty <1261319+gusty@users.noreply.github.com>
Date: Sun, 11 Oct 2020 13:42:54 +0200
Subject: [PATCH 02/13] + tests

---
 tests/FSharpPlus.Tests/Expr.fs                | 31 +++++++++++++++++++
 .../FSharpPlus.Tests/FSharpPlus.Tests.fsproj  |  8 +++++
 2 files changed, 39 insertions(+)
 create mode 100644 tests/FSharpPlus.Tests/Expr.fs

diff --git a/tests/FSharpPlus.Tests/Expr.fs b/tests/FSharpPlus.Tests/Expr.fs
new file mode 100644
index 000000000..497937ee7
--- /dev/null
+++ b/tests/FSharpPlus.Tests/Expr.fs
@@ -0,0 +1,31 @@
+namespace FSharpPlus.Tests
+
+open System
+open NUnit.Framework
+open FSharpPlus
+open FSharpPlus.Tests.Helpers
+
+module Expr =
+
+    let ``Simple quotation combination`` evaluator =
+        let one = <@ 1 @>
+        let add10AndToString x =
+            let a = string (x + 10)
+            <@ a @>
+
+        let expr = one >>= add10AndToString
+        let res = Expr.run evaluator expr
+
+        areEqual "11" res
+
+    [<Test>]
+    let ``Simple quotation combination (QuotationEvaluator)`` () =
+        ``Simple quotation combination`` FSharp.Quotations.Evaluator.QuotationEvaluator.EvaluateUntyped
+
+    [<Test>]
+    let ``Simple quotation combination (Unquote)`` () =
+        ``Simple quotation combination`` Swensen.Unquote.Operators.evalRaw
+    
+    [<Test>]
+    let ``Simple quotation combination (PowerPack)`` () =
+        ``Simple quotation combination`` Microsoft.FSharp.Linq.QuotationEvaluator.EvaluateUntyped 
\ No newline at end of file
diff --git a/tests/FSharpPlus.Tests/FSharpPlus.Tests.fsproj b/tests/FSharpPlus.Tests/FSharpPlus.Tests.fsproj
index 68a2efc4f..632c8cf31 100644
--- a/tests/FSharpPlus.Tests/FSharpPlus.Tests.fsproj
+++ b/tests/FSharpPlus.Tests/FSharpPlus.Tests.fsproj
@@ -15,6 +15,7 @@
     <Compile Include="General.fs" />
     <Compile Include="Validations.fs" />
     <Compile Include="Free.fs" />
+    <Compile Include="Expr.fs" />
     <Compile Include="ComputationExpressions.fs" />
     <Compile Include="Lens.fs" />
     <Compile Include="Extensions.fs" />
@@ -32,7 +33,9 @@
     <ProjectReference Include="..\CSharpLib\CSharpLib.csproj" />
   </ItemGroup>
   <ItemGroup>
+    <PackageReference Include="FSPowerPack.Linq.Community" Version="3.0.0" />
     <PackageReference Include="System.Runtime" Version="4.3.1" />
+    <PackageReference Include="Unquote" Version="5.0.0" />
     <PackageReference Update="FSharp.Core" Version="4.6.2" />
     <PackageReference Include="MathNet.Numerics.FSharp" Version="4.8.1" />
     <PackageReference Include="NUnit" Version="3.11.0" />
@@ -40,4 +43,9 @@
     <PackageReference Include="NUnit3TestAdapter" Version="3.11.0" />
     <PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.9.0" />
   </ItemGroup>
+  <ItemGroup Condition="'$(TargetFramework)' == 'netcoreapp3.0'">
+    <PackageReference Include="FSharp.Quotations.Evaluator">
+      <Version>2.1.0</Version>
+    </PackageReference>
+  </ItemGroup>
 </Project>

From a7870f4712dadcf2c63c92f42f127dd5eadbd73b Mon Sep 17 00:00:00 2001
From: Gusty <1261319+gusty@users.noreply.github.com>
Date: Sun, 11 Oct 2020 14:05:11 +0200
Subject: [PATCH 03/13] Comment out test

---
 tests/FSharpPlus.Tests/Expr.fs | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/tests/FSharpPlus.Tests/Expr.fs b/tests/FSharpPlus.Tests/Expr.fs
index 497937ee7..b52c60c1e 100644
--- a/tests/FSharpPlus.Tests/Expr.fs
+++ b/tests/FSharpPlus.Tests/Expr.fs
@@ -18,9 +18,9 @@ module Expr =
 
         areEqual "11" res
 
-    [<Test>]
-    let ``Simple quotation combination (QuotationEvaluator)`` () =
-        ``Simple quotation combination`` FSharp.Quotations.Evaluator.QuotationEvaluator.EvaluateUntyped
+    // [<Test>]
+    // let ``Simple quotation combination (QuotationEvaluator)`` () =
+    //     ``Simple quotation combination`` FSharp.Quotations.Evaluator.QuotationEvaluator.EvaluateUntyped
 
     [<Test>]
     let ``Simple quotation combination (Unquote)`` () =

From 505a751d7b26dea36cbfce4acacb79babcf9a75b Mon Sep 17 00:00:00 2001
From: Gusty <1261319+gusty@users.noreply.github.com>
Date: Sun, 11 Oct 2020 14:19:35 +0200
Subject: [PATCH 04/13] Fable-off

---
 src/FSharpPlus/Extensions/Expr.fs | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/src/FSharpPlus/Extensions/Expr.fs b/src/FSharpPlus/Extensions/Expr.fs
index abcb4f149..d1e0e3c22 100644
--- a/src/FSharpPlus/Extensions/Expr.fs
+++ b/src/FSharpPlus/Extensions/Expr.fs
@@ -1,5 +1,7 @@
 namespace FSharpPlus
 
+#if !FABLE_COMPILER
+
 /// Additional operations on Quotations.Expr
 [<RequireQualifiedAccess>]
 module Expr =
@@ -33,4 +35,6 @@ module Expr =
         eval (subsExpr exp)
     
     /// Executes quoted expression, given a quotation evaluator function.
-    let run (eval: Expr -> obj) (exp: Expr<'T>) : 'T = runWithUntyped eval exp.Raw null :?> 'T
\ No newline at end of file
+    let run (eval: Expr -> obj) (exp: Expr<'T>) : 'T = runWithUntyped eval exp.Raw null :?> 'T
+
+#endif
\ No newline at end of file

From 029eb1459203119e03b8b2c62ba61446dca8f6ec Mon Sep 17 00:00:00 2001
From: Gusty <1261319+gusty@users.noreply.github.com>
Date: Sun, 11 Oct 2020 14:37:07 +0200
Subject: [PATCH 05/13] Fable again

---
 src/FSharpPlus/Control/Monad.fs | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/src/FSharpPlus/Control/Monad.fs b/src/FSharpPlus/Control/Monad.fs
index ac148e153..e6ac44348 100644
--- a/src/FSharpPlus/Control/Monad.fs
+++ b/src/FSharpPlus/Control/Monad.fs
@@ -20,6 +20,7 @@ type Bind =
     static member        (>>=) (source: seq<'T>    , f: 'T -> seq<'U>     ) = Seq.bind f source                                             : seq<'U>
     #if !FABLE_COMPILER
     static member        (>>=) (source: Task<'T>   , f: 'T -> Task<'U>    ) = source.ContinueWith(fun (x: Task<_>) -> f x.Result).Unwrap () : Task<'U>
+    static member        (>>=) (source: Expr<'T>   , f: 'T -> Expr<'U>    ) = Expr.bind f source                                            : Expr<'U>
     static member        (>>=) (source             , f: 'T -> _           ) = Nullable.bind f source                                        : Nullable<'U>
     #endif
     static member        (>>=) (source             , f: 'T -> _           ) = Option.bind   f source                                        : option<'U>
@@ -35,8 +36,6 @@ type Bind =
     static member        (>>=) (source             , k: 'T -> _           ) = Result.bind k source                                          : Result<'U,'E>
     static member        (>>=) (source             , k: 'T -> _           ) = Choice.bind k source                                          : Choice<'U,'E>
 
-    static member        (>>=) (source: Expr<'T>   , f: 'T -> Expr<'U>    ) = Expr.bind f source                                            : Expr<'U>
-
     static member (>>=) (source: Map<'Key,'T>, f: 'T -> Map<'Key,'U>) = Map (seq {
                    for KeyValue(k, v) in source do
                        match Map.tryFind k (f v) with

From 4b431800d4e24cdb31228fcfd26a982bf3c656cd Mon Sep 17 00:00:00 2001
From: Gusty <1261319+gusty@users.noreply.github.com>
Date: Sun, 11 Oct 2020 15:43:12 +0200
Subject: [PATCH 06/13] + 2-layers test

---
 tests/FSharpPlus.Tests/Expr.fs | 28 ++++++++++++++++++++++++----
 1 file changed, 24 insertions(+), 4 deletions(-)

diff --git a/tests/FSharpPlus.Tests/Expr.fs b/tests/FSharpPlus.Tests/Expr.fs
index b52c60c1e..54c976a85 100644
--- a/tests/FSharpPlus.Tests/Expr.fs
+++ b/tests/FSharpPlus.Tests/Expr.fs
@@ -18,14 +18,34 @@ module Expr =
 
         areEqual "11" res
 
+    let unquote   x = Swensen.Unquote.Operators.evalRaw x
+    let powerpack x = Microsoft.FSharp.Linq.QuotationEvaluator.EvaluateUntyped x
+    
     // [<Test>]
     // let ``Simple quotation combination (QuotationEvaluator)`` () =
     //     ``Simple quotation combination`` FSharp.Quotations.Evaluator.QuotationEvaluator.EvaluateUntyped
 
     [<Test>]
-    let ``Simple quotation combination (Unquote)`` () =
-        ``Simple quotation combination`` Swensen.Unquote.Operators.evalRaw
+    let ``Simple quotation combination [Unquote]`` () = ``Simple quotation combination`` unquote
+    
+    [<Test>]
+    let ``Simple quotation combination [PowerPack]`` () = ``Simple quotation combination`` powerpack
+
+
+    let ``2-layers quotation combination`` evaluator =
+        let expr = 
+            <@ 4 + 5 @>
+            >>= fun x ->
+                let a = x + 10
+                <@  (a, a*a) @>
+            >>= fun (x, y) ->
+                <@  ([x + y], x, y, [|x; y|]) @>
+        let res = Expr.run evaluator expr
+
+        areEqual ([380], 19, 361, [|19; 361|]) res
+
+    [<Test>]
+    let ``2-layers quotation combination [Unquote]`` () = ``2-layers quotation combination`` unquote
     
     [<Test>]
-    let ``Simple quotation combination (PowerPack)`` () =
-        ``Simple quotation combination`` Microsoft.FSharp.Linq.QuotationEvaluator.EvaluateUntyped 
\ No newline at end of file
+    let ``2-layers quotation combination [PowerPack]`` () = ``2-layers quotation combination`` powerpack
\ No newline at end of file

From 3d046767f9815b3751fcba42efaf2bc5f1bde85d Mon Sep 17 00:00:00 2001
From: Gusty <1261319+gusty@users.noreply.github.com>
Date: Sun, 11 Oct 2020 15:58:24 +0200
Subject: [PATCH 07/13] test associativity

---
 tests/FSharpPlus.Tests/Expr.fs | 25 ++++++++++++++++++++++---
 1 file changed, 22 insertions(+), 3 deletions(-)

diff --git a/tests/FSharpPlus.Tests/Expr.fs b/tests/FSharpPlus.Tests/Expr.fs
index 54c976a85..f593f79b0 100644
--- a/tests/FSharpPlus.Tests/Expr.fs
+++ b/tests/FSharpPlus.Tests/Expr.fs
@@ -35,9 +35,28 @@ module Expr =
     let ``2-layers quotation combination`` evaluator =
         let expr = 
             <@ 4 + 5 @>
+            >>= (fun x ->
+                    let a = x + 10
+                    <@  (a, a*a) @>
+                    >>= fun (x, y) ->
+                        <@  ([x + y], x, y, [|x; y|]) @>)
+        let res = Expr.run evaluator expr
+
+        areEqual ([380], 19, 361, [|19; 361|]) res
+
+    [<Test>]
+    let ``2-layers quotation combination [Unquote]`` () = ``2-layers quotation combination`` unquote
+    
+    [<Test>]
+    let ``2-layers quotation combination [PowerPack]`` () = ``2-layers quotation combination`` powerpack
+
+
+    let ``2-layers quot comb associative`` evaluator =
+        let expr = 
+            (<@ 4 + 5 @>
             >>= fun x ->
                 let a = x + 10
-                <@  (a, a*a) @>
+                <@  (a, a*a) @>)
             >>= fun (x, y) ->
                 <@  ([x + y], x, y, [|x; y|]) @>
         let res = Expr.run evaluator expr
@@ -45,7 +64,7 @@ module Expr =
         areEqual ([380], 19, 361, [|19; 361|]) res
 
     [<Test>]
-    let ``2-layers quotation combination [Unquote]`` () = ``2-layers quotation combination`` unquote
+    let ``2-layers quot comb associative [Unquote]`` () = ``2-layers quot comb associative`` unquote
     
     [<Test>]
-    let ``2-layers quotation combination [PowerPack]`` () = ``2-layers quotation combination`` powerpack
\ No newline at end of file
+    let ``2-layers quot comb associative [PowerPack]`` () = ``2-layers quot comb associative`` powerpack
\ No newline at end of file

From 23f82042535a779db907141a321500e05f559fa3 Mon Sep 17 00:00:00 2001
From: Gusty <1261319+gusty@users.noreply.github.com>
Date: Sun, 11 Oct 2020 16:17:41 +0200
Subject: [PATCH 08/13] test CE

---
 tests/FSharpPlus.Tests/Expr.fs | 19 ++++++++++++++++++-
 1 file changed, 18 insertions(+), 1 deletion(-)

diff --git a/tests/FSharpPlus.Tests/Expr.fs b/tests/FSharpPlus.Tests/Expr.fs
index f593f79b0..4789463f0 100644
--- a/tests/FSharpPlus.Tests/Expr.fs
+++ b/tests/FSharpPlus.Tests/Expr.fs
@@ -67,4 +67,21 @@ module Expr =
     let ``2-layers quot comb associative [Unquote]`` () = ``2-layers quot comb associative`` unquote
     
     [<Test>]
-    let ``2-layers quot comb associative [PowerPack]`` () = ``2-layers quot comb associative`` powerpack
\ No newline at end of file
+    let ``2-layers quot comb associative [PowerPack]`` () = ``2-layers quot comb associative`` powerpack
+
+
+    let ``simple computation expression`` evaluator =
+        let expr = monad {
+            let! x = <@ 1 @>
+            let! y = <@ "2" @>
+            return! <@ string x + y @>
+        }
+        let res = Expr.run evaluator expr
+        
+        areEqual "12" res
+
+    [<Test>]
+    let ``simple computation expression [Unquote]`` () = ``simple computation expression`` unquote
+    
+    [<Test>]
+    let ``simple computation expression [PowerPack]`` () = ``simple computation expression`` powerpack
\ No newline at end of file

From f53ce2d9323f051e79265569666d1f40ea5aee20 Mon Sep 17 00:00:00 2001
From: Gusty <1261319+gusty@users.noreply.github.com>
Date: Sun, 11 Oct 2020 17:10:08 +0200
Subject: [PATCH 09/13] + CE test same type (int)

---
 tests/FSharpPlus.Tests/Expr.fs | 23 ++++++++++++++++++++---
 1 file changed, 20 insertions(+), 3 deletions(-)

diff --git a/tests/FSharpPlus.Tests/Expr.fs b/tests/FSharpPlus.Tests/Expr.fs
index 4789463f0..7705fd1fd 100644
--- a/tests/FSharpPlus.Tests/Expr.fs
+++ b/tests/FSharpPlus.Tests/Expr.fs
@@ -70,7 +70,24 @@ module Expr =
     let ``2-layers quot comb associative [PowerPack]`` () = ``2-layers quot comb associative`` powerpack
 
 
-    let ``simple computation expression`` evaluator =
+    let ``simple CE same type`` evaluator =
+        let expr = monad {
+            let! x = <@ 1 @>
+            let! y = <@ 2 @>
+            return! <@ x + y @>
+        }
+        let res = Expr.run evaluator expr
+        
+        areEqual 3 res
+
+    [<Test>]
+    let ``simple CE same type [Unquote]`` () = ``simple CE same type`` unquote
+    
+    [<Test>]
+    let ``simple CE same type [PowerPack]`` () = ``simple CE same type`` powerpack
+
+
+    let ``simple CE different types`` evaluator =
         let expr = monad {
             let! x = <@ 1 @>
             let! y = <@ "2" @>
@@ -81,7 +98,7 @@ module Expr =
         areEqual "12" res
 
     [<Test>]
-    let ``simple computation expression [Unquote]`` () = ``simple computation expression`` unquote
+    let ``simple CE different types [Unquote]`` () = ``simple CE different types`` unquote
     
     [<Test>]
-    let ``simple computation expression [PowerPack]`` () = ``simple computation expression`` powerpack
\ No newline at end of file
+    let ``simple CE different types [PowerPack]`` () = ``simple CE different types`` powerpack
\ No newline at end of file

From 07f74a78b46dc6e982e2ec02c3ae0ea3c1f8a20e Mon Sep 17 00:00:00 2001
From: Gusty <1261319+gusty@users.noreply.github.com>
Date: Sun, 11 Oct 2020 17:21:04 +0200
Subject: [PATCH 10/13] Use Unbox instead of Coerce

---
 src/FSharpPlus/Extensions/Expr.fs | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/src/FSharpPlus/Extensions/Expr.fs b/src/FSharpPlus/Extensions/Expr.fs
index d1e0e3c22..99b3380fa 100644
--- a/src/FSharpPlus/Extensions/Expr.fs
+++ b/src/FSharpPlus/Extensions/Expr.fs
@@ -15,12 +15,16 @@ module Expr =
 
     let [<Literal>] private opSliceName = "SpliceExpression"
     let [<Literal>] private opSliceType = "ExtraTopLevelOperators"
+    let [<Literal>] private ubSliceName = "Unbox"
+    let [<Literal>] private ubSliceType = "Operators"
 
     let private fsCoreAs = AppDomain.CurrentDomain.GetAssemblies () |> Seq.find (fun a -> a.GetName().Name = "FSharp.Core")
     let private miSplice = fsCoreAs.GetType(fsNamespace + "." + opSliceType).GetMethod opSliceName
+    let private ubSplice = fsCoreAs.GetType(fsNamespace + "." + ubSliceType).GetMethod ubSliceName
         
     let bind (f: 'T -> Expr<'U>) (x: Expr<'T>) : Expr<'U> =
-        Expr.Coerce (Expr.Call (miSplice.MakeGenericMethod typeof<'U>, [Expr.Application (Expr.Value f, x)]), typeof<'U>)
+        Expr.Call (ubSplice.MakeGenericMethod typeof<'U>,
+            [Expr.Call (miSplice.MakeGenericMethod typeof<'U>, [Expr.Application (Expr.Value f, x)])])
         |> Expr.Cast
 
     let rec runWithUntyped (eval: Expr -> obj) (exp: Expr) s =

From a297d5205498c9b50ed9204380a7964458a24057 Mon Sep 17 00:00:00 2001
From: Gusty <1261319+gusty@users.noreply.github.com>
Date: Sun, 11 Oct 2020 18:48:28 +0200
Subject: [PATCH 11/13] Try include QuotationsEvaluator

---
 tests/FSharpPlus.Tests/Expr.fs                 | 7 ++++---
 tests/FSharpPlus.Tests/FSharpPlus.Tests.fsproj | 6 +-----
 2 files changed, 5 insertions(+), 8 deletions(-)

diff --git a/tests/FSharpPlus.Tests/Expr.fs b/tests/FSharpPlus.Tests/Expr.fs
index 7705fd1fd..732fe2843 100644
--- a/tests/FSharpPlus.Tests/Expr.fs
+++ b/tests/FSharpPlus.Tests/Expr.fs
@@ -18,12 +18,13 @@ module Expr =
 
         areEqual "11" res
 
+    let quotseval x = FSharp.Quotations.Evaluator.QuotationEvaluator.EvaluateUntyped x
     let unquote   x = Swensen.Unquote.Operators.evalRaw x
     let powerpack x = Microsoft.FSharp.Linq.QuotationEvaluator.EvaluateUntyped x
     
-    // [<Test>]
-    // let ``Simple quotation combination (QuotationEvaluator)`` () =
-    //     ``Simple quotation combination`` FSharp.Quotations.Evaluator.QuotationEvaluator.EvaluateUntyped
+    
+    [<Test>]
+    let ``Simple quotation combination [QuotationEvaluator]`` () = ``Simple quotation combination`` quotseval
 
     [<Test>]
     let ``Simple quotation combination [Unquote]`` () = ``Simple quotation combination`` unquote
diff --git a/tests/FSharpPlus.Tests/FSharpPlus.Tests.fsproj b/tests/FSharpPlus.Tests/FSharpPlus.Tests.fsproj
index 632c8cf31..4fa16ed1b 100644
--- a/tests/FSharpPlus.Tests/FSharpPlus.Tests.fsproj
+++ b/tests/FSharpPlus.Tests/FSharpPlus.Tests.fsproj
@@ -33,6 +33,7 @@
     <ProjectReference Include="..\CSharpLib\CSharpLib.csproj" />
   </ItemGroup>
   <ItemGroup>
+    <PackageReference Include="FSharp.Quotations.Evaluator" Version ="2.1.0"/>
     <PackageReference Include="FSPowerPack.Linq.Community" Version="3.0.0" />
     <PackageReference Include="System.Runtime" Version="4.3.1" />
     <PackageReference Include="Unquote" Version="5.0.0" />
@@ -43,9 +44,4 @@
     <PackageReference Include="NUnit3TestAdapter" Version="3.11.0" />
     <PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.9.0" />
   </ItemGroup>
-  <ItemGroup Condition="'$(TargetFramework)' == 'netcoreapp3.0'">
-    <PackageReference Include="FSharp.Quotations.Evaluator">
-      <Version>2.1.0</Version>
-    </PackageReference>
-  </ItemGroup>
 </Project>

From d3f2e08e89a090adecfbf3693710550d990b058c Mon Sep 17 00:00:00 2001
From: Gusty <1261319+gusty@users.noreply.github.com>
Date: Sun, 11 Oct 2020 20:48:53 +0200
Subject: [PATCH 12/13] Use conditionals

---
 tests/FSharpPlus.Tests/Expr.fs                 | 7 ++++++-
 tests/FSharpPlus.Tests/FSharpPlus.Tests.fsproj | 6 +++++-
 2 files changed, 11 insertions(+), 2 deletions(-)

diff --git a/tests/FSharpPlus.Tests/Expr.fs b/tests/FSharpPlus.Tests/Expr.fs
index 732fe2843..844217eac 100644
--- a/tests/FSharpPlus.Tests/Expr.fs
+++ b/tests/FSharpPlus.Tests/Expr.fs
@@ -18,7 +18,12 @@ module Expr =
 
         areEqual "11" res
 
-    let quotseval x = FSharp.Quotations.Evaluator.QuotationEvaluator.EvaluateUntyped x
+    let quotseval x =
+#if NETSTANDARD
+        FSharp.Quotations.Evaluator.QuotationEvaluator.EvaluateUntyped x
+#else
+        Swensen.Unquote.Operators.evalRaw x
+#endif
     let unquote   x = Swensen.Unquote.Operators.evalRaw x
     let powerpack x = Microsoft.FSharp.Linq.QuotationEvaluator.EvaluateUntyped x
     
diff --git a/tests/FSharpPlus.Tests/FSharpPlus.Tests.fsproj b/tests/FSharpPlus.Tests/FSharpPlus.Tests.fsproj
index 4fa16ed1b..632c8cf31 100644
--- a/tests/FSharpPlus.Tests/FSharpPlus.Tests.fsproj
+++ b/tests/FSharpPlus.Tests/FSharpPlus.Tests.fsproj
@@ -33,7 +33,6 @@
     <ProjectReference Include="..\CSharpLib\CSharpLib.csproj" />
   </ItemGroup>
   <ItemGroup>
-    <PackageReference Include="FSharp.Quotations.Evaluator" Version ="2.1.0"/>
     <PackageReference Include="FSPowerPack.Linq.Community" Version="3.0.0" />
     <PackageReference Include="System.Runtime" Version="4.3.1" />
     <PackageReference Include="Unquote" Version="5.0.0" />
@@ -44,4 +43,9 @@
     <PackageReference Include="NUnit3TestAdapter" Version="3.11.0" />
     <PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.9.0" />
   </ItemGroup>
+  <ItemGroup Condition="'$(TargetFramework)' == 'netcoreapp3.0'">
+    <PackageReference Include="FSharp.Quotations.Evaluator">
+      <Version>2.1.0</Version>
+    </PackageReference>
+  </ItemGroup>
 </Project>

From 513b1ee1fea7b1880321783af403063b1f7c7c27 Mon Sep 17 00:00:00 2001
From: Gusty <1261319+gusty@users.noreply.github.com>
Date: Sun, 11 Oct 2020 21:41:44 +0200
Subject: [PATCH 13/13] Add it everywhere

---
 tests/FSharpPlus.Tests/Expr.fs | 64 ++++++++++++++--------------------
 1 file changed, 26 insertions(+), 38 deletions(-)

diff --git a/tests/FSharpPlus.Tests/Expr.fs b/tests/FSharpPlus.Tests/Expr.fs
index 844217eac..9c327d949 100644
--- a/tests/FSharpPlus.Tests/Expr.fs
+++ b/tests/FSharpPlus.Tests/Expr.fs
@@ -7,17 +7,6 @@ open FSharpPlus.Tests.Helpers
 
 module Expr =
 
-    let ``Simple quotation combination`` evaluator =
-        let one = <@ 1 @>
-        let add10AndToString x =
-            let a = string (x + 10)
-            <@ a @>
-
-        let expr = one >>= add10AndToString
-        let res = Expr.run evaluator expr
-
-        areEqual "11" res
-
     let quotseval x =
 #if NETSTANDARD
         FSharp.Quotations.Evaluator.QuotationEvaluator.EvaluateUntyped x
@@ -26,16 +15,23 @@ module Expr =
 #endif
     let unquote   x = Swensen.Unquote.Operators.evalRaw x
     let powerpack x = Microsoft.FSharp.Linq.QuotationEvaluator.EvaluateUntyped x
+
+
     
-    
-    [<Test>]
-    let ``Simple quotation combination [QuotationEvaluator]`` () = ``Simple quotation combination`` quotseval
+    let ``Simple quotation combination`` evaluator =
+        let one = <@ 1 @>
+        let add10AndToString x =
+            let a = string (x + 10)
+            <@ a @>
 
-    [<Test>]
-    let ``Simple quotation combination [Unquote]`` () = ``Simple quotation combination`` unquote
+        let expr = one >>= add10AndToString
+        let res = Expr.run evaluator expr
+
+        areEqual "11" res
     
-    [<Test>]
-    let ``Simple quotation combination [PowerPack]`` () = ``Simple quotation combination`` powerpack
+    let [<Test>] ``Simple quotation combination [QuotationEvaluator]`` () = ``Simple quotation combination`` quotseval
+    let [<Test>] ``Simple quotation combination [Unquote]``            () = ``Simple quotation combination`` unquote
+    let [<Test>] ``Simple quotation combination [PowerPack]``          () = ``Simple quotation combination`` powerpack
 
 
     let ``2-layers quotation combination`` evaluator =
@@ -50,11 +46,9 @@ module Expr =
 
         areEqual ([380], 19, 361, [|19; 361|]) res
 
-    [<Test>]
-    let ``2-layers quotation combination [Unquote]`` () = ``2-layers quotation combination`` unquote
-    
-    [<Test>]
-    let ``2-layers quotation combination [PowerPack]`` () = ``2-layers quotation combination`` powerpack
+    let [<Test>] ``2-layers quotation combination [QuotationEvaluator]`` () = ``2-layers quotation combination`` quotseval
+    let [<Test>] ``2-layers quotation combination [Unquote]``            () = ``2-layers quotation combination`` unquote
+    let [<Test>] ``2-layers quotation combination [PowerPack]``          () = ``2-layers quotation combination`` powerpack
 
 
     let ``2-layers quot comb associative`` evaluator =
@@ -69,11 +63,9 @@ module Expr =
 
         areEqual ([380], 19, 361, [|19; 361|]) res
 
-    [<Test>]
-    let ``2-layers quot comb associative [Unquote]`` () = ``2-layers quot comb associative`` unquote
-    
-    [<Test>]
-    let ``2-layers quot comb associative [PowerPack]`` () = ``2-layers quot comb associative`` powerpack
+    let [<Test>] ``2-layers quot comb associative [QuotationEvaluator]`` () = ``2-layers quot comb associative`` quotseval
+    let [<Test>] ``2-layers quot comb associative [Unquote]``            () = ``2-layers quot comb associative`` unquote
+    let [<Test>] ``2-layers quot comb associative [PowerPack]``          () = ``2-layers quot comb associative`` powerpack
 
 
     let ``simple CE same type`` evaluator =
@@ -86,11 +78,9 @@ module Expr =
         
         areEqual 3 res
 
-    [<Test>]
-    let ``simple CE same type [Unquote]`` () = ``simple CE same type`` unquote
-    
-    [<Test>]
-    let ``simple CE same type [PowerPack]`` () = ``simple CE same type`` powerpack
+    let [<Test>] ``simple CE same type [QuotationEvaluator]`` () = ``simple CE same type`` quotseval
+    let [<Test>] ``simple CE same type [Unquote]``            () = ``simple CE same type`` unquote
+    let [<Test>] ``simple CE same type [PowerPack]``          () = ``simple CE same type`` powerpack
 
 
     let ``simple CE different types`` evaluator =
@@ -103,8 +93,6 @@ module Expr =
         
         areEqual "12" res
 
-    [<Test>]
-    let ``simple CE different types [Unquote]`` () = ``simple CE different types`` unquote
-    
-    [<Test>]
-    let ``simple CE different types [PowerPack]`` () = ``simple CE different types`` powerpack
\ No newline at end of file
+    let [<Test>] ``simple CE different types [QuotationEvaluator]`` () = ``simple CE different types`` quotseval
+    let [<Test>] ``simple CE different types [Unquote]``            () = ``simple CE different types`` unquote
+    let [<Test>] ``simple CE different types [PowerPack]``          () = ``simple CE different types`` powerpack
\ No newline at end of file