1

I want to implement a pattern matching over types of case class. Caurrently I have this idea in mind:

val T = typeOf[Int]
val S = typeOf[String]
// other primitive types
val O = typeOf[Option[_]]  // doesn't work for all generic types
val X = typeOf[AnyRef]     // doesn't work at all

typeOf[A].members.filter(!_.isMethod).map(_.typeSignature).foreach {
  case T => println("int")
  case S => println("string")
  // other primitive types
  case O => println("option")
  case X => println("other")
}

But I have a two problems:

  1. How to create a type which would match any Option, List or Map in spite of there generic types?
  2. How to create a type which would match any other custom types?

Any ideas would be appreciated.

Lyashko Kirill
  • 513
  • 3
  • 14
  • Types don't exist at runtime, and pattern matching can only happen at runtime. So all you can do is match on their runtime classes; which is usually considered a code smell even in **Java**. - What is the meta-problem you are trying to solve? – Luis Miguel Mejía Suárez May 06 '23 at 14:15
  • I agree with Luis that it's not clear what your actual goal is. I think it would help if you showed what you want usage at the call site to look like. But if you can use Scala 3, perhaps Scala 3's match types would help you; the code you've provided looks something like a type-level match. https://docs.scala-lang.org/scala3/reference/new-types/match-types.html – Seth Tisue May 07 '23 at 00:36
  • The idea which I had to write a custom serialiser and deserialiser. So I just want to go over class fields and do some action based on it's type. The scala reflection is new thing to me, so was just struggling a bit with want to do there. – Lyashko Kirill May 11 '23 at 11:22

1 Answers1

0

The solution which I was able to find:

val T = typeOf[Int]
val S = typeOf[String]

typeOf[A].members.filter(!_.isMethod).map(_.typeSignature).foreach {
  case T => println("int")
  case S => println("string")
  // other primitive types
  case x if x.erasure =:= typeOf[Option[Any]] => println("option")
  case x if x <:< typeOf[AnyRef] => println("other")
}
Lyashko Kirill
  • 513
  • 3
  • 14