加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

Scala – Co / Contra-Variance应用于隐式参数选择

发布时间:2020-12-16 19:07:24 所属栏目:安全 来源:网络整理
导读:我有一个这样的特质: trait CanFold[-T,R] { def sum(acc: R,elem: T): R def zero: R} 具有如下功能: def sum[A,B](list: Traversable[A])(implicit adder: CanFold[A,B]): B = list.foldLeft(adder.zero)((acc,e) = adder.sum(acc,e)) 目的是做这样的事
我有一个这样的特质:

trait CanFold[-T,R] {
  def sum(acc: R,elem: T): R
  def zero: R
}

具有如下功能:

def sum[A,B](list: Traversable[A])(implicit adder: CanFold[A,B]): B = 
  list.foldLeft(adder.zero)((acc,e) => adder.sum(acc,e))

目的是做这样的事情:

implicit def CanFoldSeqs[A] = new CanFold[Traversable[A],Traversable[A]] {
  def sum(x: Traversable[A],y: Traversable[A]) = x ++ y
  def zero = Traversable()
}

sum(List(1,2,3) :: List(4,5) :: Nil)
//=> Traversable[Int] = List(1,3,4,5)

所以它是一个类型的类型,环境已经知道如何折叠,并可以定义为Ints,Strings,无论如何.

我的问题是,我也想具有更多具体的优先级,如下所示:

implicit def CanFoldSets[A] = new CanFold[Set[A],Set[A]] {
  def sum(x: Set[A],y: Set[A]) = x ++ y
  def zero = Set.empty[A]
}

sum(Set(1,2) :: Set(3,4) :: Nil)
//=> Set[Int] = Set(1,4)

但是,该方法调用会产生冲突,因为有歧义:

both method CanFoldSeqs in object ...
and method CanFoldSets in object ...
match expected type CanFold[Set[Int],B]

所以我想要的是编译器搜索任何和我的类型之间最具体的隐含.其目的是为基本类型提供默认实现,可以轻松地覆盖更多特定子类型,而不会影响哪些是丑陋的.

我可能希望在这里想,但只能希望:-)

解决方法

在这种情况下的通常方法利用了继承优先级的方式:

trait LowPriorityCanFoldInstances {
  implicit def CanFoldSeqs[A] = new CanFold[Traversable[A],Traversable[A]] {
    def sum(x: Traversable[A],y: Traversable[A]) = x ++ y
    def zero = Traversable()
  }
}

object CanFoldInstances extends LowPriorityCanFoldInstances {
  implicit def CanFoldSets[A] = new CanFold[Set[A],Set[A]] {
    def sum(x: Set[A],y: Set[A]) = x ++ y
    def zero = Set.empty[A]
  }
}

import CanFoldInstances._

现在,Set实例将在适用时被使用,但是如果不可用,则可以使用Traversable.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读