具有自定义类型绑定的无形映射和子类型多态 [英] Shapeless mapping and subtype polymorphism with custom type bound

查看:77
本文介绍了具有自定义类型绑定的无形映射和子类型多态的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

尝试映射自定义多态类的HList,我得到了可怕的找不到参数映射器的隐式值"错误.代码示例:

Trying to map an HList of a custom polymorphic class I'm getting the dreaded "could not find implicit value for parameter mapper" error. A code sample:

import shapeless._

trait SubTrait
case class A() extends SubTrait
case class B() extends SubTrait

case class C[T <: SubTrait](x: T)

object TheMapper extends Poly1 {
  implicit def default[T <: SubTrait, L[T] <: C[T]] = at[L[T]](_.x)
}

val ab = C(A()) :: C(B()) :: HNil

println(ab.map(TheMapper))

如果L [T]的界例如是可迭代(请参见这个非常相似的问题,解决方案和注释).我想念什么?

This works fine if the bound for L[T] is e.g. Iterable (see this very similar question, solution, and comments). What am I missing?

推荐答案

由于某种原因,真正的错误被吞没了.如果您在REPL中逐步编译此错误,则会收到此错误:

For some reason the real error gets swallowed. If you compile this step by step in the REPL you'll get this error:

error: type arguments [T] do not conform to class C's type parameter bounds [T <: SubTrait]
         implicit def default[T <: SubTrait, L[T] <: C[T]] = at[L[T]](_.x)
                                                     ^

问题在于L[T] <: C[T]中的TT <: SubTrait中的T不同.如果重命名,它将变得更具可读性:

The problem is that the T in L[T] <: C[T] is not the same as the one in T <: SubTrait. It gets more readable if you rename it:

scala> object TheMapper extends Poly1 {
     |   implicit def default[T <: SubTrait, L[x] <: C[x]] = at[L[T]](_.x)
     | }
<console>:18: error: type arguments [x] do not conform to class C's type parameter bounds [T <: SubTrait]
         implicit def default[T <: SubTrait, L[x] <: C[x]] = at[L[T]](_.x)
                                                     ^

解决方案是对x设置约束.

The solution is to put a bound on x.

scala> object TheMapper extends Poly1 {
     |   implicit def default[T <: SubTrait, L[x <: SubTrait] <: C[x]] = at[L[T]](_.x)
     | }
defined object TheMapper

scala> val ab = C(A()) :: C(B()) :: HNil
ab: shapeless.::[C[A],shapeless.::[C[B],shapeless.HNil]] = C(A()) :: C(B()) :: HNil

scala> println(ab.map(TheMapper))
A() :: B() :: HNil

这篇关于具有自定义类型绑定的无形映射和子类型多态的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆