Closed
Description
Apparently, for contravariant typeclasses, an instance for Nothing
is ambiguous with instances for List[T]
and Option[T]
. That blocks instance resolution for something as simple as List()
.
I'm not sure whether this is an issue with the spec or with the implementation; I suppose this was an oversight. But it's enough to make instance resolution for Show
unusable for us, so much that in #4437 people are proposing to drop Show
altogether (also for unrelated reasons). Here's the puzzler:
trait Show[-T] { def show(x: T): String; def instName: String }
implicit def showOption[T]: Show[Option[T]] = new Show { def show(x: Option[T]) = "showOption"; def instName = "showOption" } // XXX
scala> implicitly[Show[Nothing]].instName
val res5: String = "showOption"
scala> implicit def showNothing: Show[Nothing] = new Show[Nothing] { def show(x: Nothing) = ""; def instName = "showNothing" }
implicit val showNothing: Show[Nothing]
scala> implicitly[Show[Nothing]].instName
val res6: String = "showNothing"
scala> implicit def showList[T]: Show[List[T]] = new Show { def show(x: List[T]) = "showList"; def instName = "showList" } // XXX
implicit val showList[T] => Show[List[T]]
scala> implicitly[Show[Nothing]].instName
1 |implicitly[Show[Nothing]].instName
| ^
|ambiguous implicit arguments: both method showList and method showNothing match type Show[Nothing] of parameter ev of method implicitly in object DottyPredef
- also investigate covariant and instances for
Any
, regardless that it's maybe less of a problem