另一个分歧的隐含扩张

时间:2016-04-24 22:44:23

标签: scala implicit shapeless

我遇到了“分歧隐式扩展”错误,无法找到问题所在。

有一些虚拟类来隔离问题:

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]()

这是我的错,但我仍然不清楚为什么我们需要懒惰,所以问题仍然存在。

0 个答案:

没有答案