我有一个Nat的HList,我想要映射它
object NatToString extends Poly1 {
implicit def caseNat = at[Nat](_.toString)
}
val list = _5 :: _3 :: HNil
list.map(NatToString)
Run Code Online (Sandbox Code Playgroud)
此代码不编译并抛出:
找不到参数映射器的隐含值:
shapeless.ops.hlist.Mapper [Main.Nat_to_String.type,shapeless.:: [shapeless.Nat._5,shapeless.:: [shapeless.Nat._3,shapeless.HNil]] ]
但是,如果我用Int(或String,或List等)代替Nat做同样的事情,它就完美无缺.
我如何映射Nat的HList?
问题是Poly1.Case它的类型参数不是协变的.考虑以下:
trait Foo
trait Bar extends Foo
val foo = new Foo {}
var bar = new Bar {}
object fooIdentity extends Poly1 {
implicit def caseFoo = at[Foo](identity)
}
Run Code Online (Sandbox Code Playgroud)
现在fooIdentity(foo)将编译,但fooIdentity(bar)不会.
在您的情况下,HList静态类型的成员为_5和_3.这些是子类型Nat,但NatToString并不关心,因为它唯一的情况是寻找静态类型的东西Nat.
诀窍就是在案例中添加一个类型参数:
object NatToString extends Poly1 {
implicit def caseNat[N <: Nat] = at[N](_.toString)
}
Run Code Online (Sandbox Code Playgroud)
你会发现,一般来说,Nat直接使用并不是你想要的 - 你几乎总是想要一个特定的子类型.
| 归档时间: |
|
| 查看次数: |
231 次 |
| 最近记录: |