Мой исходный код:
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
, что, на первый взгляд, неудивительно. Я попытался исправить ошибку, добавив еще один имплицит, который должен срабатывать при отсутствии 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
или нет?