Scala隐式优先排序系统
我有一个关于隐性优先权制度的问题。我有以下代码:Scala隐式优先排序系统,scala,implicit,Scala,Implicit,我有一个关于隐性优先权制度的问题。我有以下代码: 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
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
}
只是想知道为什么反向变量如何帮助编译器进行优先级排序。理想情况下,我想一步一步地介绍两个案例,以说明其中一个有效,而另一个失败的原因
谢谢
只是想知道为什么反向变量如何帮助编译器进行优先级排序
反向变量show无助于确定优先级。如果删除它,隐式仍将解决
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)
}
}
重要的是类型类的差异。CatShow是不变的,MyShow是逆变的。当您在寻找隐式[CatShow[Plain]]时,只有catShowPlain是候选项。当你在寻找隐式[MyShow[Plain]]和隐式[MyShow[Any]时,因为隐式[MyShow[Any]感谢你的回答,特别是你发布的帖子,它向我解释了很多。最后要了解的是:最初的CatShow也可以隐式处理[CatShow[Random]]如果您有另一个random case类。这应该意味着CatShow[Any]可以以某种方式符合CatShow[Plain]的条件。这一部分也让我感到困惑。@w_vv如果您不添加新的隐式,原始CatShow无法隐式处理case类Randomi:Int的[CatShow[random]]未编译。请编写完整的代码。@w_vv CatShow[Any]和CatShow[Plain]不是不变CatShow的连接类型。您是对的……看起来另一个隐式的方法使show StringContext在cats中工作。非常感谢