dimanche 11 avril 2021

TypeTest to overcome erasure with generic types in scala3

I am having problems understanding how TypeTests in scala3 can replace the use of TypeTag in scala 2. The usecase being able to match on a generic parameter like x: List[Int].

Concrete example I am trying to solve:

enum Foo :
  case Bar()
  case Baz()

case class Mod[T <: Foo](modFn: T => T)

def modifyBarsOrBaz(mod: Mod[_]) = mod match
  case barMod: Mod[Foo.Bar] => ???
  case bazMod: Mod[Foo.Baz] => ???

the compilation results (as expected) in the comiler warning(s)

the type test for Mod[Foo.Bar] cannot be checked at runtime and an unreachable case.

Now my question is: is this possible to do at all in scala3?

I was under the impression that I would somehow have to provide a TypeTest[Any, Mod[Foo.X]] for all X which are subclasses of the Foo enum.

But I am struggling to even implement those tests, as well as understanding what using parameter the modifyBarsOrBaz is required for this to work.

Thus I came up with the following (not working) solution:

def modifyBarsOrBaz[T <: Foo](mod: Mod[T])(using TypeTest[Any, Mod[T]]) = mod match
  case barMod: Mod[Foo.Bar] => ???
  case bazMod: Mod[Foo.Baz] => ???

and a naive tt implementation as such

val tt: TypeTest[Any, Mod[Foo.Bar]] =
  new TypeTest[Any, Mod[Foo.Bar]] :
    def unapply(x: Any): Option[x.type & Mod[Foo.Bar]] = x match
      case m: Mod[_] => ??? // what to do here? use a classtag on Mod?

I tried to search the web for answers, but since this is pretty new I was not lucky. Any hints?





Aucun commentaire:

Enregistrer un commentaire