Create TypeRepr of a type with projection #16305
Answered
by
KacperFKorban
pomadchin
asked this question in
Metaprogramming
-
What is the right way to build up a Short version:// given
trait ServiceK[U[_[_]]] // ServiceK is just to demo the usage, the culprit is IdK[A]#λ
type IdK[A] = { type λ[F[_]] = F[A] } It's possible to create the following What is the right way to build up // this is a non working pseudocode
TypeRef(
TypeRepr.of[IdK].appliedTo(TypeRepr.of[Int]),
λ // <--- this one
) A Longer version:// given
trait ServiceK[U[_[_]]]
type IdK[A] = { type λ[F[_]] = F[A] }
// macro function itself
def idK(using Quotes): Expr[Boolean] = {
import quotes.reflect.*
// There is a need to construct the following TypeRepr via primitives
// The problem is in IdK[Int]#λ but when written this way it's easier to get what I'm trying to do
// also the println(expected) is much nicer
val expected = TypeRepr.of[ServiceK[IdK[Int]#λ]]
// expected println
// AppliedType(
// TypeRef(TermRef(ThisType(TypeRef(NoPrefix,module class com)),object test),ServiceK),
// List(
// TypeRef(
// AppliedType(
// TypeRef(ThisType(TypeRef(TermRef(ThisType(TypeRef(NoPrefix,module class com)),object test),Test$)),IdK),List(TypeRef(TermRef(ThisType(TypeRef(NoPrefix,module class <root>)),object scala),Int))),
// λ
// )
// )
// )
// I could not find a way to build the IdK[Int]#λ projection here
val actual = TypeRepr.of[ServiceK].appliedTo(TypeRepr.of[IdK].appliedTo(TypeRepr.of[Int]))
// this is a non working pseudocode
// val actual = TypeRepr.of[ServiceK].appliedTo(
// TypeRef(TypeRepr.of[IdK].appliedTo(TypeRepr.of[Int]), λ)
// )
Expr(actual =:= expected)
}
|
Beta Was this translation helpful? Give feedback.
Answered by
KacperFKorban
Nov 9, 2022
Replies: 1 comment 3 replies
-
A way to build it manually would be to do something like this: import scala.quoted.*
trait ServiceK[U[_[_]]]
type IdK[A] = {
type λ[F[_]] = F[A]
}
inline def idK: Boolean = ${ idKImpl }
def idKImpl(using Quotes): Expr[Boolean] = {
import quotes.reflect.*
val expected = TypeRepr.of[ServiceK[IdK[Int]#λ]]
// IdK[Int] is encoded as
// java.lang.Object {
// type λ >: [F >: scala.Nothing <: [_$3 >: scala.Nothing <: scala.Any] => scala.Any] => F[scala.Int] <: [F >: scala.Nothing <: [_$3 >: scala.Nothing <: scala.Any] => scala.Any] => F[scala.Int]
// }
// i.e. a Refinement type (Object + the type declaration)
TypeRepr.of[IdK].appliedTo(TypeRepr.of[Int]) match {
case repr: Refinement =>
val actual = TypeRepr.of[ServiceK].appliedTo(repr.info)
Expr(actual =:= expected)
}
} Though I am not sure if that will be the intended way. |
Beta Was this translation helpful? Give feedback.
3 replies
Answer selected by
KacperFKorban
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
A way to build it manually would be to do something like this: