Given that i have a kind of enumeration using a sealed trait and case objects representing the values, is it possible to enforce a mechanism to retrieve the single unique value for a given type, without requiring an implicit argument?
with implicits this would be
sealed trait Enum
sealed trait Value1 extends Enum
case object Value1 extends Value1 { implicit val me: Value1 = Value1 }
sealed trait Value2 extends Enum
case object Value2 extends Value2 { implicit val me: Value1 = Value1 }
def test[V <: Enum](implicit evidence: V): V = evidence
test[Value1]
is it possible to drop the implicit argument to test? that is, to ensure that V is a defined subtype of Enum (obviously, test[Enum] should fail). the gordian knot is:
object Enum {
def unique[V <: Enum]: V = ???
}
?
It looks as though you're trying to look up specific values or behaviour based on type and, for whatever reason don't want to put this behaviour in some common superclass.
It also looks as though you're trying to use implicits and companion objects to achieve this by emulating some of the characteristics of Java's statics. This is a model you absolutely want to be dropping from your mental toolkit, it's hopelessly broken from the perspective of object oriented programming.
What you really want is ad-hoc polymorphism, and we have better ways to do that. Interestingly, it does still use implicits, and a context bound:
You could also define
test
as:Which does exactly the same thing, manually removing the syntactic sugar of context bounds that the compiler would do for you anyway.
Basically, it all works because the compile will also consider type params when resolving implicits.
If you want to read up more on this kind of thing, the magic prhrase to search for is "type classes"