0

Given I'm using reflection to go through a list of members (giving me runtime.universe.Symbol), how can I check the generic type without the type arguments? In other words, how do I find the members which are List[] generic type, regardless of what the type argument is?

Currently I'm using this approach which does work, but I'm wondering if there's a better way to do it:

import scala.reflect.runtime.currentMirror

// ...

val listTypeConstructor = typeOf[List[_]].typeConstructor
val myListMembers = currentMirror.reflect(MyObject)
  .symbol
  .asClass
  .typeSignature
  .members
  .filter(member => member.typeSignature.resultType.typeConstructor == listTypeConstructor)

This results in a list of runtime.universe.Symbol of all the List[] members, including any List[String], List[Int], etc. as expected.

The usage of typeOf[List[_]].typeConstructor seems a bit messy to me though. Is this the best way to do this kind of filtering?

Dmytro Mitin
  • 48,194
  • 3
  • 28
  • 66
Daniel
  • 8,655
  • 5
  • 60
  • 87
  • What you are looking for actually is not List[_] (as you already know), and the thing is, the generic type itself does not have a constructor, like List itself. so getting the constructor and filtering that in the last step won't work. also, https://stackoverflow.com/questions/37011958/how-to-obtain-generic-type-at-runtime-in-scala might help – AminMal Sep 25 '21 at 05:35
  • Why do you consider using `typeOf[List[_]].typeConstructor` messy? `typeOf[List[_]]` is `scala.reflect.runtime.universe.Type` of the existential type `List[_]` while `typeOf[List[_]].typeConstructor` is `scala.reflect.runtime.universe.Type` of the type constructor `List`. – Dmytro Mitin Sep 25 '21 at 09:40
  • @DmytroMitin that's a good point. My feelings derive from the fact that I'm passing `_` to `List[]`, and I haven't looked into `TypeTag`s yet but I think that may address my "messy" complaint. But the more I look at it the more it makes sense. Would you say my code above is indeed the best way to do this filtering then? – Daniel Sep 25 '21 at 14:13
  • 1
    @Daniel Using `typeOf[TC[_]].typeConstructor` seems pretty standard https://github.com/milessabin/shapeless/blob/main/core/src/main/scala/shapeless/annotation.scala#L286-L288 https://github.com/milessabin/shapeless/blob/main/core/src/main/scala/shapeless/generic.scala#L260-L270 – Dmytro Mitin Sep 26 '21 at 01:23

1 Answers1

0

The answer is no. The way I have it in the example above is the standard way.

Daniel
  • 8,655
  • 5
  • 60
  • 87