我的初始代码:
sealed trait Adder[L <: HList, U] extends DepFn2[L, Vector[U]]
object Adder {
def apply[L <: HList, U: Ordering](implicit adder: Adder[L, U]): Aux[L, U, adder.Out] = adder
type Aux[L <: HList, U, Out0] = Adder[L, U] { type Out = Out0 }
implicit def found[T <: HList, U: Ordering]: Aux[Vector[U] :: T, U, Vector[U] :: T] =
new Adder[Vector[U] :: T, U] {
type Out = Vector[U] :: T
def apply(l: Vector[U] :: T, collection: Vector[U]): Out = {
(l.head ++ collection).sorted :: l.tail
}
}
implicit def notFound[H, T <: HList, U: Ordering, OutT <: HList](implicit ut: Aux[T, U, OutT]): Aux[H :: T, U, H :: OutT] =
new Adder[H :: T, U] {
type Out = H :: OutT
def apply(l: H :: T, collection: Vector[U]): Out = {
val outT = ut(l.tail, collection)
l.head :: outT
}
}
implicit def empty[U: Ordering]: Aux[HNil, U, Vector[U] :: HNil] =
new Adder[HNil, U] {
type Out = Vector[U] :: HNil
def apply(l: HNil, collection: Vector[U]): Out = collection :: HNil
}
}
我发现了一个错误,即没有上下文绑定的事物Ordering
通过类型notFound
而不是传递found
,这在hinsight中并不令人惊讶。我试图通过添加另一个隐式来修复该错误,该隐式应在没有此隐式时触发Ordering
:
implicit def foundNoOrdering[T <: HList, U]: Aux[Vector[U] :: T, U, Vector[U] :: T] =
new Adder[Vector[U] :: T, U] {
type Out = Vector[U] :: T
def apply(l: Vector[U] :: T, collection: Vector[U]): Out = {
l.head ++ collection :: l.tail
}
}
但是,这导致foundNoOrdering
和之间的含糊不清found
。如何根据是否存在不同的代码路径Ordering
?
标准技巧是通过将隐式变量放在祖先特征中来降低优先级
object Adder extends LowPriorityAdderImplicits {
implicit def found...
}
trait LowPriorityAdderImplicits {
implicit def foundNoOrdering....
}
您会在标准库中找到其中一些。LowPriorityImplicits似乎是习惯名称。
在规范中:
如果有多个与隐式参数的类型匹配的合格参数,则将使用静态重载解析规则(第6.26.3节)选择一个最具体的参数。
如果满足以下条件之一,则从类或对象D派生类或对象C:
•C是D的子类,或者
•C是从D派生的类的伴侣对象,或者
•D是派生C的类的伴随对象。
并使其更加具体,并在解决方案中获得优先考虑。我相信那是为隐性而做的。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句