|
| 1 | +package cps |
| 2 | + |
| 3 | +import scala.quoted._ |
| 4 | + |
| 5 | +trait CpsMonad[F[_]] |
| 6 | + |
| 7 | +trait ComputationBound[T] |
| 8 | + |
| 9 | +implicit object ComputationBoundMonad extends CpsMonad[ComputationBound] |
| 10 | + |
| 11 | +inline def async[F[_]](using am:CpsMonad[F]): Async.InferAsyncArg[F] = |
| 12 | + new Async.InferAsyncArg[F] |
| 13 | + |
| 14 | +object PFHelper { |
| 15 | + def create[X,Y](x:Boolean):PartialFunction[X,Y] = ??? |
| 16 | +} |
| 17 | + |
| 18 | +object Async { |
| 19 | + |
| 20 | + class InferAsyncArg[F[_]](using am:CpsMonad[F]) { |
| 21 | + |
| 22 | + inline def apply[T](inline expr: T):Unit = |
| 23 | + ${ |
| 24 | + Async.transformImpl[F,T]('expr) |
| 25 | + } |
| 26 | + |
| 27 | + } |
| 28 | + |
| 29 | + def transformImpl[F[_]:Type,T:Type](f: Expr[T])(using Quotes): Expr[Unit] = |
| 30 | + import quotes.reflect._ |
| 31 | + |
| 32 | + def uninline(t:Term):Term = |
| 33 | + t match |
| 34 | + case Inlined(_,_,x) => uninline(x) |
| 35 | + case _ => t |
| 36 | + |
| 37 | + val fu = uninline(f.asTerm) |
| 38 | + fu match |
| 39 | + case Block(_,Apply(TypeApply(Select(q,n),tparams),List(param))) => |
| 40 | + param.tpe match |
| 41 | + case AppliedType(tp,tparams1) => |
| 42 | + val fromTypeOrBounds = tparams1.head |
| 43 | + val fromType = fromTypeOrBounds match |
| 44 | + case bounds: TypeBounds => bounds.low |
| 45 | + case tp: TypeRepr => tp |
| 46 | + case np: NoPrefix => ??? |
| 47 | + val toType = tparams1.tail.head |
| 48 | + val fType = TypeRepr.of[F] |
| 49 | + val toWrapped = fType.appliedTo(toType) |
| 50 | + val helper = '{ cps.PFHelper }.asTerm |
| 51 | + val helperSelect = Select.unique(helper,"create") |
| 52 | + val createPF = Apply( |
| 53 | + TypeApply(helperSelect,List(Inferred(fromType),Inferred(toWrapped))), |
| 54 | + List(Literal(BooleanConstant(true))) |
| 55 | + ) |
| 56 | + val createPfApply = Apply(Select.unique(createPF,"apply"),List(Literal(IntConstant(1)))) |
| 57 | + Block(List(createPfApply),Literal(UnitConstant())).asExpr.asInstanceOf[Expr[Unit]] |
| 58 | + |
| 59 | +} |
0 commit comments