斯卡拉的虚无与部分统一 [英] Scala's Nothing vs partial unification
问题描述
我希望以下代码能够正常编译:
特征Widen [M [_]] {def widen [A,B> ;: A](ma:M [A]):M [B]}物件扩大{隐式类Ops [M [_],A](ma:M [A]){def widen [B> ;: A](隐式ev:Widen [M]):M [B] = ev.widen [A,B](ma)}//隐式类OpsNothing [M [_]](ma:M [Nothing]){//def widen [B](隐式ev:Widen [M]):M [B] = ev.widen(ma)//}隐式val WidenList = new Widen [List] {def widen [A,B> ;: A](l:List [A]):List [B] = l}}导入Widen._List.empty [Some [Int]].widen [Option [Int]]List.empty [Nothing] .widen [Int]//在取消注释OpsNothing之前不会编译
但是最后一行不编译.这似乎与部分统一有关,因为 new Widen.Ops [List,Nothing](List.empty [Nothing]).widen [Int]
确实可以编译.
现在真正奇怪的是,如果我取消注释 Nothing
的特殊情况,则所有内容都会编译.
我不知道发生了什么事...
(这使用的是Scala 2.13.3)
编译器不希望在解析隐式时推断 Nothing
对于<:< 的无"失败的隐式解析失败>
除了 OpsNothing
之外的另一种解决方法是键入 Bottom
type底部< ;:无List.empty [Bottom] .widen [Int]//编译
I would expect the following code to compile just fine:
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
But the last line does not compile. It seems to be related to partial unification because new Widen.Ops[List, Nothing](List.empty[Nothing]).widen[Int]
does compile.
Now what's really weird is that if I uncomment the special case for Nothing
then everything compiles.
I have no idea what's going on...
(This is using Scala 2.13.3)
Compiler doesn't like to infer Nothing
while resolving implicits
Failed implicit resolution for Nothing with <:<
Another workaround besides OpsNothing
is type Bottom
type Bottom <: Nothing
List.empty[Bottom].widen[Int] // compiles
这篇关于斯卡拉的虚无与部分统一的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!