Based on the example here https://github.com/lampepfl/dotty-macro-examples/blob/main/primaryConstructor/src/macros.scala I trying to create a macro that will create an instance of a class. The minimized code is
package test
import scala.quoted._
object TypeConstructor {
inline def creator[V, F]: V => F = ${impl[V, F]}
private def impl[V: Type, F: Type](using q: Quotes): Expr[V => F] = {
import q.reflect._
val fTpr = TypeRepr.of[F]
val ctor = fTpr.typeSymbol.primaryConstructor
def VToF(in: Expr[V]): Expr[F] =
New(TypeTree.of[F]).select(ctor).appliedTo(in.asTerm).asExprOf[F]
'{ (v: V) => ${ VToF('v) } }
}
}
This seems to work fine, except when used together with an F
that has a type parameter. For example
package test
object Test {
case class A[T](a: T)
val creatorA = TypeConstructor.creator[String, A[String]]
}
fails to compile with
-- Error: construct_scala3_test.scala:5:17 --------------------------------------------------------------------------------------------------------------------
5 | val creatorA = TypeConstructor.creator[String, A[String]]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| constructor A in class A does not take parameters
1 error found
To me it not clear how I should tweak the macro code such that it also works correctly for types with type parameters?