Scala 隐式优先级系统

标签 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 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 会帮助编译器确定优先级。理想情况下,我想一步一步地通过两个案例来说明为什么一个成功而另一个失败。

谢谢

最佳答案

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)
  }
}

重要的是类型类别的差异。 CatShow是不变的并且 MyShow是逆变的。当您寻找implicitly[CatShow[Plain]]时仅catShowPlain是一名候选人。当您寻找implicitly[MyShow[Plain]]时两者myShowAny (因为 implicitly[MyShow[Any] <:< MyShow[Plain]] )和 myShowPlain是候选人。他们因为原因而产生歧义Why is this implicit ambiguity behaviour happening?

关于Scala 隐式优先级系统,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60850189/

相关文章:

python - 如何将数据拟合到非理想二极管方程(隐式非线性函数)并检索参数

C++,隐式转换/构造函数是如何确定的?

scala - Apache Spark - 两个样本 Kolmogorov-Smirnov 测试

python - 如何在 Pyspark 中使用 Scala 类

scala - 使用 sbt-native-packager 的任何好例子

scala - 如何将Scala作业提交给Spark?

python - python 和 scala 之间的 zeromq 请求-回复模式

scala - 以不同的方式链式运作

Scala:泛型和隐式

scala - 从父类(super class)型解析隐式参数