在Scala中的隐式实例中强制执行优先级 [英] Enforcing precedence in implicit instances in Scala

查看:98
本文介绍了在Scala中的隐式实例中强制执行优先级的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是对问题伴侣中的标量隐式类型优先级的跟踪对象.

假设我有两个特征,Trait2 extends Trait1.每个特征都有一个特定的Eq类型类实例.我想让Trait2的typeclass实例的优先级高于Trait1的tha.但是,下面的代码(LowPriorityImplicits技巧)不起作用.

Suppose that I have two traits, Trait2 extends Trait1. Each trait has a specific typeclass instance of Eq. I'd like to let the precedence of the typeclass instance of Trait2 to be higher than tha of Trait1. However, the code below (the LowPriorityImplicits trick) does not work.

trait Eq[-A] {
  def eq(a: A, b: A): Boolean
}

object Eq {
  implicit object IntEq extends Eq[Int] {
    def eq(a: Int, b: Int) = a == b
  }
}

trait Trait1[+A]
trait Trait2[+A] extends Trait1[A]

object Implicits extends LowPriorityImplicits {
  implicit def Eq2[T: Eq]: Eq[Trait2[T]] = ???
}

trait LowPriorityImplicits {
  implicit def Eq1[T: Eq]: Eq[Trait1[T]] = ???
}

object Test2 extends App {

  def f[T: Eq](x: T) = ???
  import Implicits._

  val t1 = new Trait1[Int] {}
  val t2 = new Trait2[Int] {}

  f(t2) // COMPILATION ERROR!

}

抛出以下编译错误:

Error:(33, 4) ambiguous implicit values:
 both method Eq1 in trait LowPriorityImplicits of type [T](implicit evidence$2: Eq[T])Eq[Trait1[T]]
 and method Eq2 in object Implicits of type [T](implicit evidence$1: Eq[T])Eq[Trait2[T]]
 match expected type Eq[Trait2[Int]]
  f(t2)
   ^

如何强制类型类实例的优先级关系?

How can I enforce the precedence relation of the typeclass instances?

推荐答案

类型参数中的差异与Scala的类型类编码不太匹配.如果要编译,只需尝试一下即可.

Variance in type parameters doesn't play well with Scala's encoding of type classes. If you want it to compile, simply try this.

trait Eq[A] {
  def eq(a: A, b: A): Boolean
}

object Eq {
  implicit object IntEq extends Eq[Int] {
    def eq(a: Int, b: Int) = a == b
  }
}

trait Trait1[A]
trait Trait2[A] extends Trait1[A]

object Implicits extends LowPriorityImplicits {
  implicit def Eq2[T: Eq]: Eq[Trait2[T]] = ???
}

trait LowPriorityImplicits {
  implicit def Eq1[T: Eq]: Eq[Trait1[T]] = ???
}

object Test2 extends App {

  def f[T: Eq](x: T) = ???
  import Implicits._

  val t1 = new Trait1[Int] {}
  val t2 = new Trait2[Int] {}

  f(t2) // COMPILATION ERROR!

}

如果您确实希望Eq[Trait2[A]]的行为类似于Eq[Trait1[A]]的子类型,则可以使用隐式转换作为解决方法.

If you do want Eq[Trait2[A]] to behave like a sub-type of Eq[Trait1[A]], you might be able to use implicit conversions as a workaround.

这篇关于在Scala中的隐式实例中强制执行优先级的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆