The problem with implicit ambiguity between my method and matches in Predef

The following code, taken from the excellent Apocalisp blog series: Scala level programming and modified for the implicit parsing script. 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 explain why this happens and if it is fixed?

 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) } } 
+2
source share
1 answer

Although I cannot tell you the exact purpose of Predef.conforms , I can tell you that the ambiguity error seems correct (unfortunately). In a comment in the source, he even says that <:< was introduced due to the ambiguity problems of Function1 (says Function2 , but I think this is a mistake). But since <:< is a subclass of Function1 , it can be passed when Function1 is expected, so in your case it can be passed to <:< in hparse.

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

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

I see two possible solutions:

  • just delete hParseNil , I think your code is still working.
  • Shadow Predef conforms , calling the same:

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

+5
source

Source: https://habr.com/ru/post/900350/


All Articles