Reputation: 434
I'm contributing to scala 3 library that does compile time type verification and I've encountered following issue.
I'm having type hierarchy like this:
trait Match[V <: String]
type Alphanumeric = Match["^[a-zA-Z0-9]+"]
trait RegexChecker[MatchType] {
inline def checkRegex(text: String): Boolean
}
inline given RegexChecker[Alphanumeric] with {
inline def checkRegex(text: String): Boolean = ???
}
In implicit RegexChecker I would like to extract regex pattern from Alphanumeric type and use it for computation - unfortunately I can't find a way to do it. Because everything is just a type I cannot pass Alphanumeric like this def extractor[T](dummy: Match[T])
to extract using constValue
. I was looking into macros and I was trying to match my type like this:
def extractorMacro()(using Quotes, Type[T]): Expr[String] = {
import quotes.reflect.*
val tpe = TypeRepr.of[T]
val r = tpe.asType match
case '[ Match[v] {type Match$V = a } ] => ???
case '[ Match[String] { type V = q }] => ???
case _ => "fail"
But unfortunately none of cases work despite compiling properly (example from ScalaDoc for valueOfConstant does not really work, because I don't have Expr - I have just Type).
Upvotes: 1
Views: 174
Reputation: 27535
This could be done easier with ValueOf
inline def regexp[S <: String: ValueOf] =
summon[ValueOf[S]].value.r
regexp["[0-9]+"]
Then without macro:
trait Match[V <: String]
type Alphanumeric = Match["^[a-zA-Z0-9]+"]
// implementation
trait RegexCheckerImpl[S <: String]:
inline def checkRegex(text: String): Boolean
inline given [S <: String: ValueOf]: RegexCheckerImpl[S] with
inline def checkRegex(text: String): Boolean =
summon[ValueOf[S]].value.r.matches(text)
// match types to turn RegexChecker[Match[A]]
// into RegexCheckerImpl[A]
type RegexChecker[MA] = MA match
case Match[a] => RegexCheckerImpl[a]
summon[RegexChecker[Alphanumeric]].checkRegex("10")
Upvotes: 1