Scala 隐式优先级系统
Scala Implicit Prioritisation system
我有一个与隐式优先系统相关的问题。我有以下代码:
object MyMain extends App {
case class Plain(s: String)
// cats version
trait CatShow[T] extends ContravariantShow[T]
object CatShow {
def apply[A](implicit instance: CatShow[A]): CatShow[A] = instance
trait ContravariantShow[-T] extends Serializable {
def show(t: T): String
}
def show[A](f: A => String): CatShow[A] = new CatShow[A] {
def show(a: A): String = f(a)
}
}
// my simplified version
trait MyShow[-T] extends Serializable {
def show(t: T): String
}
object MyShow {
def apply[A](implicit instance: MyShow[A]): MyShow[A] = instance
def show[A](f: A => String): MyShow[A] = new MyShow[A] {
def show(a: A): String = f(a)
}
}
// implicits definition for both
abstract class ImplicitInstances0 extends ImplicitInstances1 {
implicit val catShowPlain: CatShow[Plain] = CatShow(_.toString + "[cat-plain]")
implicit val myShowPlain: MyShow[Plain] = MyShow(_.toString + "[my-plain]")
}
abstract class ImplicitInstances1 {
implicit val catShowAny: CatShow[Any] = CatShow(_.toString + "[cat-Any]")
implicit val myShowAny: MyShow[Any] = MyShow(_.toString + "[my-Any]")
}
object ImplicitInstances extends ImplicitInstances0
import ImplicitInstances._
implicitly[CatShow[Plain]] // works magically
implicitly[MyShow[Plain]] // [ERROR] compiler error for ambiguous implicit
}
只是想知道为什么 ContravariantShow
会帮助编译器确定优先级。理想情况下,我想通过 2 个案例逐步说明为什么一个有效而另一个失败。
谢谢
just wonder why the ContravariantShow
will help the complier for prioritisation.
ContravariantShow
无助于确定优先级。如果删除它,隐式仍将解析。
trait CatShow[T] /*extends ContravariantShow[T]*/ {
def show(t: T): String // added
}
object CatShow {
def apply[A](implicit instance: CatShow[A]): CatShow[A] = instance
// trait ContravariantShow[-T] extends Serializable {
// def show(t: T): String
// }
def show[A](f: A => String): CatShow[A] = new CatShow[A] {
def show(a: A): String = f(a)
}
}
重要的是类型的差异class。 CatShow
是不变的,MyShow
是逆变的。当您正在寻找 implicitly[CatShow[Plain]]
时,只有 catShowPlain
是候选者。当您正在寻找 implicitly[MyShow[Plain]]
时,myShowAny
(因为 implicitly[MyShow[Any] <:< MyShow[Plain]]
)和 myShowPlain
都是候选者。而他们因为
的原因搞得模棱两可
我有一个与隐式优先系统相关的问题。我有以下代码:
object MyMain extends App {
case class Plain(s: String)
// cats version
trait CatShow[T] extends ContravariantShow[T]
object CatShow {
def apply[A](implicit instance: CatShow[A]): CatShow[A] = instance
trait ContravariantShow[-T] extends Serializable {
def show(t: T): String
}
def show[A](f: A => String): CatShow[A] = new CatShow[A] {
def show(a: A): String = f(a)
}
}
// my simplified version
trait MyShow[-T] extends Serializable {
def show(t: T): String
}
object MyShow {
def apply[A](implicit instance: MyShow[A]): MyShow[A] = instance
def show[A](f: A => String): MyShow[A] = new MyShow[A] {
def show(a: A): String = f(a)
}
}
// implicits definition for both
abstract class ImplicitInstances0 extends ImplicitInstances1 {
implicit val catShowPlain: CatShow[Plain] = CatShow(_.toString + "[cat-plain]")
implicit val myShowPlain: MyShow[Plain] = MyShow(_.toString + "[my-plain]")
}
abstract class ImplicitInstances1 {
implicit val catShowAny: CatShow[Any] = CatShow(_.toString + "[cat-Any]")
implicit val myShowAny: MyShow[Any] = MyShow(_.toString + "[my-Any]")
}
object ImplicitInstances extends ImplicitInstances0
import ImplicitInstances._
implicitly[CatShow[Plain]] // works magically
implicitly[MyShow[Plain]] // [ERROR] compiler error for ambiguous implicit
}
只是想知道为什么 ContravariantShow
会帮助编译器确定优先级。理想情况下,我想通过 2 个案例逐步说明为什么一个有效而另一个失败。
谢谢
just wonder why the
ContravariantShow
will help the complier for prioritisation.
ContravariantShow
无助于确定优先级。如果删除它,隐式仍将解析。
trait CatShow[T] /*extends ContravariantShow[T]*/ {
def show(t: T): String // added
}
object CatShow {
def apply[A](implicit instance: CatShow[A]): CatShow[A] = instance
// trait ContravariantShow[-T] extends Serializable {
// def show(t: T): String
// }
def show[A](f: A => String): CatShow[A] = new CatShow[A] {
def show(a: A): String = f(a)
}
}
重要的是类型的差异class。 CatShow
是不变的,MyShow
是逆变的。当您正在寻找 implicitly[CatShow[Plain]]
时,只有 catShowPlain
是候选者。当您正在寻找 implicitly[MyShow[Plain]]
时,myShowAny
(因为 implicitly[MyShow[Any] <:< MyShow[Plain]]
)和 myShowPlain
都是候选者。而他们因为