以下代码摘自Apocalisp优秀的博客系列: Type level programming in scala,并针对隐式解析方案进行了修改。但是,这不会编译,并显示以下消息:
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)
有人可以解释为什么会发生这种情况,以及它是否可以解决?
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)
}
}
答案 0 :(得分:5)
虽然我无法准确地告诉你Predef.conforms
的目的,但我可以告诉你歧义错误似乎是正确的(不幸的是)。在源代码中的评论中,它甚至说<:<
是由于Function1
的模糊性问题而引入的(Function2
说,但我认为这是一个错误)。但由于<:<
是Function1
的子类,因此只要预期Function1
就可以传入它,因此在您的情况下可以将<:<
传递给hparse。
现在,implicit def conforms[A]: A <:< A
具有(根据我的理解)每当方法需要类型A => A
时,在范围内具有隐式值A
就足够了。 / p>
在您的情况下,implicit def hParseNil: HNil => HNil
具有与conforms
相同的优先级,因此两者都可以同等应用。
我看到两种可能的解决方案:
hParseNil
,我认为您的代码仍然可以使用。通过将您的Predef
命名为conforms
implicit def conforms: HNil => HNil = _ => new HNil
来隐藏它们:
{{1}}
答案 1 :(得分:1)
您只需将函数文字hParseNil
替换为普通函数即可。
implicit def hParseNil(a:HNil): HNil = HNil
代替
implicit def hParseNil: HNil => HNil = _ => HNil