Shapeless:持有 Prepend 和 Split 用于延迟执行
Shapeless: holding Prepend and Split for delayed execution
我的目标是包装一个 HList 并保存足够的信息以便稍后执行前置和拆分操作。
case class Wrap[L <: HList](wrapped: L)
val x = Wrap("x" :: "y" :: HNil)
val y = Wrap(1 :: 2 :: HNil)
case class Append[L1, L2](w1: Wrap[L1], w2: Wrap[L2], prepend: Prepend[L1, L2], length: Length[L1])
def append[L1, L2](w1: Wrap[L1], w2: Wrap[L2])(implicit prepend: Prepend[L1, L2], length: Length[L1]) = Append(w1, w2, prepend, length)
val xAppendY = append(x,y)
val merged = xAppendY.prepend(xAppendY.w1.wrapped, xAppendY.w2.wrapped)
val split = Split[xAppendY.prepend.Out, xAppendY.length.Out] // <-- error here
split.apply(merged)
此代码因隐式未找到错误而失败:
Implicit not found: shapeless.Ops.Split[xAppendY.prepend.Out, xAppendY.length.Out]. You requested to split at position xAppendY.length.Out, but the HList xAppendY.prepend.Out is too short.
但是编译器似乎应该知道类型是String :: String :: String :: String :: HNil
和Nat._2
。我需要做些什么来帮助编译器吗?
以下版本的代码有效:
import shapeless.ops.hlist.{Length, Prepend, Split}
import shapeless.{::, HList, HNil, Nat}
case class Wrap[L <: HList](wrapped: L)
val x = Wrap("x" :: "y" :: HNil)
val y = Wrap(1 :: 2 :: HNil)
case class Append[L1 <: HList, L2 <: HList, L3 <: HList, N <: Nat](w1: Wrap[L1], w2: Wrap[L2], prepend: Prepend.Aux[L1, L2, L3], length: Length.Aux[L1, N])
def append[L1 <: HList, L2 <: HList, L3 <: HList, N <: Nat](w1: Wrap[L1], w2: Wrap[L2])(implicit prepend: Prepend.Aux[L1, L2, L3], length: Length.Aux[L1, N]) = Append(w1, w2, prepend, length)
val xAppendY = append(x,y)
val merged = xAppendY.prepend(xAppendY.w1.wrapped, xAppendY.w2.wrapped)
val split = Split[xAppendY.prepend.Out, xAppendY.length.Out]
split.apply(merged)
在您的代码版本中,xAppendY.prepend
的类型是 Prepend[L1, L2] = Prepend[L1, L2] { type Out }
而不是 Prepend.Aux[L1, L2, L3] = Prepend[L1, L2] { type Out = L3 }
正确的 L3
并且 xAppendY.length
的类型是 Length[L1] = Length[L1] { type Out }
而不是 Length.Aux[L1, N] = Length[L1] { type Out = N }
正确 N
.
我的目标是包装一个 HList 并保存足够的信息以便稍后执行前置和拆分操作。
case class Wrap[L <: HList](wrapped: L)
val x = Wrap("x" :: "y" :: HNil)
val y = Wrap(1 :: 2 :: HNil)
case class Append[L1, L2](w1: Wrap[L1], w2: Wrap[L2], prepend: Prepend[L1, L2], length: Length[L1])
def append[L1, L2](w1: Wrap[L1], w2: Wrap[L2])(implicit prepend: Prepend[L1, L2], length: Length[L1]) = Append(w1, w2, prepend, length)
val xAppendY = append(x,y)
val merged = xAppendY.prepend(xAppendY.w1.wrapped, xAppendY.w2.wrapped)
val split = Split[xAppendY.prepend.Out, xAppendY.length.Out] // <-- error here
split.apply(merged)
此代码因隐式未找到错误而失败:
Implicit not found: shapeless.Ops.Split[xAppendY.prepend.Out, xAppendY.length.Out]. You requested to split at position xAppendY.length.Out, but the HList xAppendY.prepend.Out is too short.
但是编译器似乎应该知道类型是String :: String :: String :: String :: HNil
和Nat._2
。我需要做些什么来帮助编译器吗?
以下版本的代码有效:
import shapeless.ops.hlist.{Length, Prepend, Split}
import shapeless.{::, HList, HNil, Nat}
case class Wrap[L <: HList](wrapped: L)
val x = Wrap("x" :: "y" :: HNil)
val y = Wrap(1 :: 2 :: HNil)
case class Append[L1 <: HList, L2 <: HList, L3 <: HList, N <: Nat](w1: Wrap[L1], w2: Wrap[L2], prepend: Prepend.Aux[L1, L2, L3], length: Length.Aux[L1, N])
def append[L1 <: HList, L2 <: HList, L3 <: HList, N <: Nat](w1: Wrap[L1], w2: Wrap[L2])(implicit prepend: Prepend.Aux[L1, L2, L3], length: Length.Aux[L1, N]) = Append(w1, w2, prepend, length)
val xAppendY = append(x,y)
val merged = xAppendY.prepend(xAppendY.w1.wrapped, xAppendY.w2.wrapped)
val split = Split[xAppendY.prepend.Out, xAppendY.length.Out]
split.apply(merged)
在您的代码版本中,xAppendY.prepend
的类型是 Prepend[L1, L2] = Prepend[L1, L2] { type Out }
而不是 Prepend.Aux[L1, L2, L3] = Prepend[L1, L2] { type Out = L3 }
正确的 L3
并且 xAppendY.length
的类型是 Length[L1] = Length[L1] { type Out }
而不是 Length.Aux[L1, N] = Length[L1] { type Out = N }
正确 N
.