首页 > 解决方案 > 使用 <:< 的 Nothing 的隐式解析失败

问题描述

以下代码无法在 Scala 2.12 / 2.13 上编译。为什么?

class X[U, T]

object X {
  implicit def genericX[U, T](implicit ev: T <:< U): X[U, T] = new X[U, T]
}

implicitly[X[AnyRef, String]]  // compiles
implicitly[X[String, Nothing]] // does not compile

标签: scalaimplicit

解决方案


长话短说,编译器不喜欢Nothing隐式推断。

当类型参数之一应该是 Nothing 时,为什么 Scala 的隐式类不起作用?

尝试实现“Absurd”类型类时出现隐式错误

https://www.reddit.com/r/scala/comments/73791p/nothings_twin_brother_the_better_one/

http://guillaume.martres.me/talks/typelevel-summit-oslo/?fbclid=IwAR1yDSz-MetOgBh0uWMeuBuuL6wlD79fN_4NrxAtl3c46JB0fYCYeeGgp1Y#/9(幻灯片10“恐惧Nothing”)

https://www.youtube.com/watch?v=YIQjfCKDR5A?t=459 (7:39)

https://www.youtube.com/watch?v=lMvOykNQ4zs

的恐惧Nothing

  • scalac急切地实例化,即使它不安全

  • 通过从不推断来平衡Nothing

    class Foo[T] { def put(x: T) = {} }
    (new Foo).put("") // T? = String
    
  • 如果下限不是则失败Nothing

    class Foo[T >: Null] { def put(x: T) = {} }
    (new Foo).put("") // T? = Null
    // type mismatch: Null does not match String
    
  • 有时候你真的很想推断Nothing

    class Foo[T]
    def foo[T](x: Foo[T]) = x
    foo(new Foo[Nothing]) // error
    

解决方法是引入类型Bottom

type Bottom <: Nothing

implicitly[Bottom =:= Nothing]
implicitly[Nothing =:= Bottom]

implicitly[X[AnyRef, String]]  // compiles
// implicitly[X[String, Nothing]] // does not compile
implicitly[X[String, Bottom]] // compiles

推荐阅读