gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-12-04 01:57:21 24 4
gpt4 key购买 nike

我有这样的特质:

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, 2, 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, 2, 3, 4)

但是,该方法调用会产生冲突,因为存在歧义:
both method CanFoldSeqs in object ...
and method CanFoldSets in object ...
match expected type CanFold[Set[Int], B]

所以我想要的是编译器在 Any 和我的类型之间搜索最具体的隐式。目的是为基本类型提供默认实现,可以为更具体的子类型轻松覆盖这些基本类型,而不会产生难看的阴影。

我可能一厢情愿地想在这里,但只能希望:-)

最佳答案

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

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 的实例不可用时仍然可用。

关于Scala - 应用于隐式参数选择的 Co/Contra-Variance,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13195574/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com