HList
のいくつかの種類のより高い種類に一致する暗黙のdefを使用して再帰的なHList
型を構築しています。私は大きくthis postに触発されています。このコードは完璧に働いている暗黙的なdefのスカラー上位の型が "暗黙の値を見つけることができませんでした"と失敗しました
:
今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"
を、私はなぜ知らないが、私は単に既存のHList.++
メソッドを呼び出しますHCons
に++
メソッドを追加しようとした場合、これが動作していません。
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)
}
私は、このコンパイルエラーを取得:
could not find implicit value for parameter f: Appender[HCons[T,U],L2,HCons[T,U]#Plus[L2]]
HCons
は、HList。++で定義されているL1タイプのように、HList
のサブタイプであるため、OKだと思っていました。
私はこれを試してみたが、それは良く働いていない:
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)))
}
私は何を逃したのですか?
感謝:)あなたはこのことから、あなたの++
メソッドの定義を変更する必要があります
私はあなたのやっていることに従わないようにしましたが、3行目の ':HList'は赤い旗です。 'HList'は何のためにも静的型としては無用です。 –
ありがとう、実際には、HListから継承したケースクラスによってオーバーロードされています – Loic
私は混乱を少なくして削除しましたが、動作は同じです – Loic