Suppose I have several auto-generated classes, like MyEnum1
, MyEnum2
, ... (they are not necessarily Scala enum types, just some auto-generated classes). Though the type of MyEnum1
is different than the type of MyEnum2
(and they share no auto-generated parent types except Any
), I can guarantee that all of these auto-generated types have exactly the same public, static methods available, in particular findById
and findByName
, which allow looking up the enum value based on index or string name.
I am trying to create a function that would utilize the type-specific version of findById
and findByName
, but is generic to accept any of MyEnum1
, MyEnum2
, ... as the function parameter.
Note that a typical sealed trait
+ case class
pattern to create a sum type out of the different enums would not help here, because I am talking about dispatching different static methods based on a type parameter, and there is never any actual value parameter involved at all.
For example, suppose that MyEnum1
encodes male/female gender. So that MyEnum1.findById(0)
return MyEnum1.Female
which has type MyEnum1
. And say MyEnum2
encodes eye color, so that MyEnum2.findById(0)
returns MyEnum2.Green
which has type MyEnum2
.
I am given a Map where the key is the type and the value is the index to look up, such as
val typeMap = Map(
MyEnum1 -> 0,
MyEnum2 -> 0
)
and I would like to generically do this:
for ( (elemType, idx) <- typeMap ) yield elemType.findById(v)
|---------------|
the goal is to
avoid boilerplate
of defining this
with different
pattern matching
for every enum.
and get back some sequence type (can have element type Any
) that looks like
MyEnum1.Female, MyEnum2.Green, ...
I've struggled with the sealed trait
+ case class
boilerplate for a while and it does not seem to be conceptually the right way. No matter if I wrap values of MyEnum1
or MyEnum2
into case class value constructors like FromMyEnum1(e: MyEnum1)
and try to define implicits for operating on that value, it doesn't help in my code example above when I want to do elemType.findById(...)
, because the compiler still says that type Any
(what it resolves for the key type in my Map
), has no method findById
.
I'd strongly prefer to not wrap the types themselves in a case class pattern to serve as the keys, but I could do that -- except I cannot see how it's possible to treat the type itself as a first class value in a case class constructor, something naively like
case class FromMyEnum1(e: MyEnum1.getClass) extends EnumTrait
(so that the Map
keys could have type EnumTrait
and presumably there could be some implicit that matched each case class constructor to the correct implementation of findById
or findByName
).
Any help to understand how Scala enables using types themselves as the values inside of case class value constructors would be appreciated!