Ich verwende implizite Def, um eine rekursive HList
Art zu erstellen, um mehrere Arten von höher verbundenen Typen von HList
zu entsprechen. Ich bin stark inspiriert von this post.Scala höher kinked Typen im impliziten Def fehlschlägt mit "Konnte nicht impliziten Wert finden"
Dieser Code perfekt funktioniert:
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"
Nun, ich weiß nicht warum, aber wenn ich versuche, eine ++
Methode auf HCons
, hinzuzufügen, die HList.++
Methodenaufrufe einfach bestehende, dies nicht funktioniert:
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)
}
ich erhalte diese Kompilierungsfehler:
could not find implicit value for parameter f: Appender[HCons[T,U],L2,HCons[T,U]#Plus[L2]]
Da HCons
ein Untertyp von HList
ist, wie der L1-Typ, der von HList. ++ definiert wird, dachte ich, es sei OK.
Ich habe dies versucht, aber, dass die Arbeit ist nicht besser:
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)))
}
Was habe ich verpasst?
def ++[L2 <: HList](l2: L2) = HList.++(this,l2)
dazu:
Thanks :)
Ich habe nicht versucht zu folgen, was Sie tun, aber die ': HList' in Zeile drei ist eine rote Fahne. 'HList' ist als statischer Typ für irgendetwas ziemlich nutzlos. –
Danke, in der Tat ist es von Fallklassen überladen von HList – Loic
Ich habe es für weniger Verwirrung entfernt, aber das Verhalten ist das gleiche – Loic