斯卡拉的虚无与部分统一

问题描述

我希望以下代码能够正常编译:

trait Widen[M[_]] { def widen[A,B >: A](ma: M[A]): M[B] }

object Widen {
  implicit class Ops[M[_],A](ma: M[A]) {
    def widen[B >: A](implicit ev: Widen[M]): M[B] = ev.widen[A,B](ma)
  }
  // implicit class OpsNothing[M[_]](ma: M[Nothing]) {
  //   def widen[B](implicit ev: Widen[M]): M[B] = ev.widen(ma)
  // }
  implicit val WidenList = new Widen[List] { def widen[A,B >: A](l: List[A]): List[B] = l }
}

import Widen._

List.empty[Some[Int]].widen[Option[Int]]

List.empty[Nothing].widen[Int] // does not compile until uncommenting OpsNothing

但是最后一行不编译。它似乎与部分统一有关,因为new Widen.Ops[List,Nothing](List.empty[Nothing]).widen[Int]确实可以编译。

现在真正奇怪的是,如果我不评论Nothing的特殊情况,那么所有内容都会编译。

我不知道发生了什么事...

(这使用的是Scala 2.13.3)

解决方法

编译器在解析隐式函数时不喜欢推断Nothing

Failed implicit resolution for Nothing with <:<

OpsNothing之外的另一种解决方法是键入Bottom

type Bottom <: Nothing
List.empty[Bottom].widen[Int] // compiles

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...