@@ -689,6 +689,50 @@ private def sumExpr(args1: Seq[Expr[Int]])(given QuoteContext): Expr[Int] = {
689
689
}
690
690
```
691
691
692
+ #### Recovering precise types using patterns
693
+
694
+ Sometimes it is necessary to get a more precise type for an expression. This can be achived using the following pattern match.
695
+
696
+ ``` scala
697
+ def f (exp : Expr [Any ]) =
698
+ expr match
699
+ case ' { $x : $t } =>
700
+ // If the pattern match succeeds, then there is some type `T` such that
701
+ // - `x` is bound to a variable of type `Expr[T]`
702
+ // - `t` is bound to a given instance of type `Type[T]`
703
+ // That is, we have `x: Expr[T]` and `given t: Type[T]`, for some (unknown) type `T`.
704
+ ```
705
+
706
+ This might be used to then perform an implicit search as in:
707
+
708
+
709
+ ``` scala
710
+ inline def (sc : StringContext ) showMe(args : => Any * ): String = $ { showMeExpr(' sc , ' args ) }
711
+
712
+ private def showMeExpr (sc : Expr [StringContext ], argsExpr : Expr [Seq [Any ]])(given qctx : QuoteContext ): Expr [String ] = {
713
+ argsExpr match {
714
+ case ExprSeq (argExprs) =>
715
+ val argShowedExprs = argExprs.map {
716
+ case ' { $arg : $tp } =>
717
+ val showTp = ' [Show [$tp]]
718
+ summonExpr(given showTp )) match {
719
+ case Some (showExpr) => ' { $showExpr.show($arg) }
720
+ case None => qctx.error(s " could not find implicit for ${showTp.show}" , arg); ' {??? }
721
+ }
722
+ }
723
+ val newArgsExpr = Expr .ofSeq(argShowedExprs)
724
+ ' { $sc.s($newArgsExpr : _* ) }
725
+ case _ =>
726
+ // `new StringContext(...).showMeExpr(args: _*)` not an explicit `showMeExpr"..."`
727
+ qctx.error(s " Args must be explicit " , argsExpr)
728
+ ' {??? }
729
+ }
730
+ }
731
+
732
+ trait Show [- T ] {
733
+ def show (x : T ): String
734
+ }
735
+ ```
692
736
693
737
### More details
694
738
[ More details] ( ./macros-spec.md )
0 commit comments