10
聯合/孔特拉 - 方差我有一個特點是這樣的:斯卡拉 - 適用於隱含參數選擇
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,字符串,不管。
我的問題是,我想也有優先,這樣更加具體的implicits:
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]
所以我想要的是編譯器搜索任何和我的類型之間最具體的隱含。目的是爲基本類型提供默認實現,這些實現可以被更容易地替換爲更具體的子類型,而不會產生很醜的陰影。
我可以一廂情願地想在這裏,但人們只能希望:-)