@@ -135,7 +135,33 @@ expressiveness.
135135
136136### From ` Expr ` s to Functions and Back
137137
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
139165describing a function into a function mapping trees to trees.
140166``` scala
141167object Expr {
@@ -150,16 +176,6 @@ result of beta-reducing `f(x)` if `f` is a known lambda expression.
150176``` scala
151177Expr .betaReduce(_): Expr [(T1 , ..., Tn ) => R ] => ((Expr [T1 ], ..., Expr [Tn ]) => Expr [R ])
152178```
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.
163179
164180### Lifting Types
165181
0 commit comments