@@ -135,7 +135,33 @@ expressiveness.
135
135
136
136
### From ` Expr ` s to Functions and Back
137
137
138
- The ` Expr ` companion object contains a ` betaReduce ` conversion that turns a tree
138
+ It is possible to convert any ` Expr[T => R] ` into ` Expr[T] => Expr[R] ` and back.
139
+ These conversions can be implemented as follows:
140
+
141
+ ``` scala
142
+ def to [T , R ](f : Expr [T ] => Expr [R ])(using QuoteContext ): Expr [T => R ] =
143
+ ' { (x : T ) => $ { f(' x ) } }
144
+
145
+ def from [T , R ](f : Expr [T => R ])(using QuoteContext ): Expr [T ] => Expr [R ] =
146
+ (x : Expr [T ]) => ' { $f($x) }
147
+ ```
148
+
149
+ Note how the fundamental phase consistency principle works in two
150
+ different directions here for ` f ` and ` x ` . In the method ` to ` , the reference to ` f ` is
151
+ legal because it is quoted, then spliced, whereas the reference to ` x `
152
+ is legal because it is spliced, then quoted.
153
+
154
+ They can be used as follows:
155
+
156
+ ``` scala
157
+ val f1 : Expr [Int => String ] = to((x : Expr [Int ]) => ' { $x.toString }) // '{ (x: Int) => x.toString }
158
+
159
+ val f2 : Expr [Int ] => Expr [String ] = from(' { (x : Int ) => x.toString }) // (x: Expr[Int]) => '{ ((x: Int) => x.toString)($x) }
160
+ f2(' {2 }) // '{ ((x: Int) => x.toString)(2) }
161
+ ```
162
+
163
+ One limitation of ` from ` is that it does not β-reduce when a lambda is called immediately, as evidenced in the code ` { ((x: Int) => x.toString)(2) } ` .
164
+ In some cases we want to remove the lambda from the code, for this we provide the method ` Expr.betaReduce ` that turns a tree
139
165
describing a function into a function mapping trees to trees.
140
166
``` scala
141
167
object Expr {
@@ -150,16 +176,6 @@ result of beta-reducing `f(x)` if `f` is a known lambda expression.
150
176
``` scala
151
177
Expr .betaReduce(_): Expr [(T1 , ..., Tn ) => R ] => ((Expr [T1 ], ..., Expr [Tn ]) => Expr [R ])
152
178
```
153
- Its dual, let’s call it ` reflect ` , can be defined as follows:
154
- ``` scala
155
- def reflect [T , U ](f : Expr [T ] => Expr [U ]): Expr [T => U ] = ' {
156
- (x : T ) => $ { f(' x ) }
157
- }
158
- ```
159
- Note how the fundamental phase consistency principle works in two
160
- different directions here for ` f ` and ` x ` . The reference to ` f ` is
161
- legal because it is quoted, then spliced, whereas the reference to ` x `
162
- is legal because it is spliced, then quoted.
163
179
164
180
### Lifting Types
165
181
0 commit comments