我遇到了“分歧隐式扩展”错误,无法找到问题所在。
有一些虚拟类来隔离问题:
import shapeless._
type Field = String
trait Column[T]
trait Parameter
trait Row
implicit object IntColumn extends Column[Int]
implicit object DoubleColumn extends Column[Double]
trait Mapper[T] {
def unmap(l: T): Seq[Parameter]
def map(row: Row): T
}
type MapperFactory[L] = (List[Field] => Mapper[L])
object Mapper {
def apply[L](fields: List[Field] = Nil)(implicit mapper: MapperFactory[L]) = mapper(fields)
}
我希望代码能够工作或至少编译:
trait LowPriorityMapperImplicits {
implicit def fromMapper[H](implicit mapper: Mapper[H]): MapperFactory[H] = fields => mapper
}
object DivergingMapper extends LowPriorityMapperImplicits {
implicit def caseMapper[L, H <: HList](implicit generic: Generic.Aux[L, H], mapper: MapperFactory[H]): MapperFactory[L] = ???
implicit def hListMapper[H, T <: HList](implicit hMapper: MapperFactory[H], tMapper: MapperFactory[T]): MapperFactory[H :: T] = ???
implicit def hNilMapper: MapperFactory[HNil] = ???
implicit def singleMapper[H](implicit to: Column[H]): MapperFactory[H] = ???
}
以下是测试用例:
trait F[X] {
import DivergingMapper._
//import LazyMapper._
implicit protected val xMapper: Mapper[X]
// t1-t5 work
val t0 = Mapper[A]()
val t1 = Mapper[X]()
val t2 = Mapper[A]()
val t3 = Mapper[X]()
val t4 = Mapper[(A, A)]()
val t5 = Mapper[(X, А)]()
// t6-t7 don't
// diverging implicit expansion for type com.ardtrade.db.XMapper.MapperFactory[...]
// starting with method caseMapper in object XMapper
val t6 = Mapper[(A, X)]()
val t7 = Mapper[(X, X)]()
}
我无法理解为什么Mapper[(X, A)]
有效,但Mapper[(A, X)]
没有。
更新
我试图使用 shapeless.Lazy
进行编译,但是我已经让NPE从懒惰中得到了值。
尝试回答Miles Sabin的请求,发布使用Lazy导致NPE的版本,我发现我的测试用例实际编译并与Lazy版本一起使用:
object LazyMapper extends LowPriorityMapperImplicits {
implicit def caseMapper[L, H <: HList](implicit generic: Generic.Aux[L, H], mapper: MapperFactory[H]): MapperFactory[L] = ???
implicit def hListMapper[H, T <: HList](implicit hMapper: MapperFactory[H], tMapper: Lazy[MapperFactory[T]]): MapperFactory[H :: T] = ???
implicit def hNilMapper: MapperFactory[HNil] = ???
implicit def singleMapper[H](implicit to: Column[H]): MapperFactory[H] = ???
}
由于以下暗示,我有NPE:
implicit def fromMapper[H](implicit mapper: Mapper[H]): MapperFactory[H] = fields => mapper
// every time we declare a new mapper as implicit val
// and there is no way to create it properly
// we get self initialization
// with null without any compile error
implicit val nullMapper = Mapper[ABRACADABRA]()
这是我的错,但我仍然不清楚为什么我们需要懒惰,所以问题仍然存在。