zio-prelude icon indicating copy to clipboard operation
zio-prelude copied to clipboard

Issues with `Nothing` Instances

Open adamgfraser opened this issue 4 years ago • 4 comments

Seeing a couple of issues with the implicit instances for Nothing. First, instances of parameterized on Nothing such as Equal[Nothing aren't available in implicit scope. Even if I move everything other than Nothing to a lower priority scope I still get this error. I think there is some kind of logic that Nothing does not qualify as a more specific type.

trait Equal[-A]

object Equal {
  
  implicit val IntEqual: Equal[Int] =
    new Equal[Int] {}
  
  implicit val StringEqual: Equal[String] =
    new Equal[String] {}
  
  implicit val NothingEqual: Equal[Nothing] =
    new Equal[Nothing] {}
}

// diverging implicits
implicitly[Equal[Nothing]]

Also, even if I define an Equal[Nothing] instance locally to make it implicitly available derived instances aren't available unless defining them extremely explicitly:

trait Equal[-A]

object Equal {
  
  implicit def EitherEqual[A: Equal, B: Equal]: Equal[Either[A, B]] =
    new Equal[Either[A, B]] {}
  
  implicit val IntEqual: Equal[Int] =
    new Equal[Int] {}
}

implicit val NothingEqual: Equal[Nothing] =
  new Equal[Nothing] {}

implicitly[Equal[Nothing]]
implicitly[Equal[Either[Int, Nothing]]] // Does not compile
Equal.EitherEqual[Int, Nothing]

adamgfraser avatar Apr 27 '20 23:04 adamgfraser

Of course - Equal is contravariant so both Equal[Int] and Equal[String] are more specific than Equal[Nothing].

joroKr21 avatar Aug 01 '20 05:08 joroKr21

Equal is contravariant so both Equal[Int] and Equal[String] are more specific than Equal[Nothing].

That behavior is reversed in Dotty (https://github.com/lampepfl/dotty/blob/bb23fea9f5605f12650f4aa5ef8716c3237c1ac4/compiler/src/dotty/tools/dotc/typer/Applications.scala#L1482-L1512), and Scala 2 does something similar under -Xsource:3.0: https://github.com/scala/scala/pull/6037

smarter avatar Aug 01 '20 20:08 smarter

and Scala 2 does something similar under -Xsource:3.0

Oh cool, I didn't realize it was back ported. I guess this is only 2.13 though. Maybe it's reasonable to expect that most who use this library should be already on 2.13.

joroKr21 avatar Aug 02 '20 04:08 joroKr21

This is Contrarivariance: https://leanpub.com/fpmortals/read#leanpub-auto-type-variance

You'll hit this anywhere there is a subtype hierarchy. All credit to Kris Nuttycombe and Paul Phillips for first identifying the bug (which for many years was declared a feature) and naming it so well. https://github.com/scala/bug/issues/2509

fommil avatar Aug 02 '20 13:08 fommil