La escala de tipos más altos en def implícito falla con "no se pudo encontrar el valor implícito"
Estoy usando def implícito para construir un recursivoHList
tipo, para que coincida con varios tipos de tipos más altos deHList
. Estoy muy inspirado poresta publicación.
Este código funciona perfectamente:
sealed trait HList {
type Plus[L <: HList] <: HList
}
class HNil extends HList {
type Plus[L <: HList] = L
def ::[T](v: T) = HCons(v, this)
}
case class Appender[L1 <: HList, L2 <: HList, R <: HList](fn: (L1, L2) => R) {
def apply(l1: L1, l2: L2) = fn(l1, l2)
}
object HNil extends HNil
object HList {
def ++[L1 <: HList, L2 <: HList](l1: L1, l2: L2)(implicit f: Appender[L1, L2, L1#Plus[L2]]): L1#Plus[L2] = f(l1, l2)
implicit def nilAppender[L <: HList]: Appender[HNil, L, L] = Appender((v: HNil, l: L) => l)
implicit def consAppender[T, L1 <: HList, L2 <: HList, R <: HList](implicit f: Appender[L1, L2, R]): Appender[HCons[T, L1], L2, HCons[T, R]] = {
Appender[HCons[T, L1], L2, HCons[T, R]]((l1: HCons[T, L1], l2: L2) => HCons(l1.head, f(l1.tail, l2)))
}
}
case class HCons[T, U <: HList](head: T, tail: U) extends HList {
type Plus[L <: HList] = HCons[T, U#Plus[L]]
def ::[V](v: V) = HCons(v, this)
}
import HList._
val hlist1 = 2.0 :: "hi" :: HNil
val hlist2 = 1 :: HNil
val sum = ++(hlist1, hlist2)
println("last element : " : + sum.tail.tail.head) // prints last element : 1"
Ahora, no sé por qué, pero si trato de agregar un++
método enHCons
, que simplemente llama existenteHList.++
método, esto NO funciona:
case class HCons[T, U <: HList](head: T, tail: U) extends HList {
type Plus[L <: HList] = HCons[T, U#Plus[L]]
def ::[V](v: V) = HCons(v, this)
def ++[L2 <: HList](l2: L2) = HList.++(this,l2)
}
Me sale este error de compilación:
could not find implicit value for parameter f: Appender[HCons[T,U],L2,HCons[T,U]#Plus[L2]]
ComoHCons
es un subtipo deHList
, como el tipo L1 definido por HList. ++, estaba pensando que estaba bien.
He intentado esto pero no funciona mejor:
implicit def consAppender[T, L1 <: HList, L2 <: HList, L3, R <: HList](implicit f: Appender[L1, L2, R], ev: L3 <:< HCons[T, L1]): Appender[HCons[T, L1], L2, HCons[T, R]] = {
Appender[HCons[T, L1], L2, HCons[T, R]]((l1: L3, l2: L2) => HCons(l1.head, f(l1.tail, l2)))
}
¿Qué me perdí?
Gracias :)