Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
925 views
in Technique[技术] by (71.8m points)

scala - problem with implicit ambiguity between my method and conforms in Predef

The following code, which is taken from Apocalisp's excellent blog series: Type level programming in scala , and modified for an implicit parsing scenario. However, this does not compile, with the following message:

error: ambiguous implicit values:
both method hParseNil in object HApplyOps of type => (com.mystuff.bigdata.commons.collections.hlist.HNil) => com.mystuff.bigdata.commons.collections.hlist.HNil
and method conforms in object Predef of type [A]<:<[A,A]
match expected type (com.mystuff.bigdata.commons.collections.hlist.HNil) => com.amadesa.bigdata.commons.collections.hlist.HNil
val l = hparse[HNil,HNil](HNil)

Can someone please explain why this happens, and if it's fixable?

sealed trait HList

final case class HCons[H, T <: HList](head: H, tail: T) extends HList {
  def :+:[T](v: T) = HCons(v, this)
}

sealed class HNil extends HList {
  def :+:[T](v: T) = HCons(v, this)
}

object HNil extends HNil

// aliases for building HList types and for pattern matching
object HList {
  type :+:[H, T <: HList] = HCons[H, T]
  val :+: = HCons

}

object HApplyOps
{
  import HList.:+:



  implicit def hParseNil: HNil => HNil = _ => HNil

  implicit def hParseCons[InH,OutH,TIn <:HList,TOut<:HList](implicit parse:InH=>OutH,parseTail:TIn=>TOut): (InH :+: TIn) => (OutH :+: TOut) =
    in => HCons(parse(in.head),parseTail(in.tail))

  def hparse[In <: HList, Out <: HList](in:In)(implicit parse: In => Out):Out = in

}


object PG {

  import HList._


  def main(args: Array[String]) {

    import HApplyOps._

    val l = hparse[HNil,HNil](HNil)

  }
}
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Although i can't tell you exactly the purpose of Predef.conforms, i can tell you the ambiguity error seems correct (unfortunately). In the comment in the source it even says that <:< was introduced because of ambiguity problems of Function1 (says Function2 but i guess that is a mistake). But since <:< is a subclass of Function1 it can be passed in whenever Function1 is expected, so in your case its possible to pass in <:< to hparse.

Now the implicit def conforms[A]: A <:< A has the effect (from what i understand) that whenever a method expects a type A => A, it is sufficient to have an implicit value of A in scope.

In your case the implicit def hParseNil: HNil => HNil has the same priority as conforms and thus both could be equally applied.

I see two possible solutions:

  • just remove the hParseNil, i think your code still works.
  • shadow the Predef's conforms by naming yours the same:

    implicit def conforms: HNil => HNil = _ => new HNil


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...