在下面的程序中,我试图让一个类型类工作。类型类是 Algo,它的实际实现需要一个 Container[_ <: Id] 并且应该从该容器返回一个元素。但是由于某种原因,抽象特征中算法方法的返回类型和实现函数不同,即使它们应该是相同的。此外,由于某种原因,未找到隐式 def。任何人都可以阐明我做错了什么?
class Element {
}
trait Container[T <: Element] {
type ElemType = T
val value : T
}
trait Id {
}
class ElementWithId extends Element with Id
trait Algo[T <: Container[_]] {
def algo(t : T) : Option[T#ElemType]
}
object Algo {
implicit def impl[C <: Container[_ <: Id]] = new Algo[C] {
def algo(cont : C) : Option[C#ElemType] = {
Some(cont.value)
}
}
implicitly[Algo[Container[ElementWithId]]].algo(new Container[ElementWithId] {
override val value = new ElementWithId
})
}
完整的错误信息是:
[error] test.scala:126: type mismatch;
[error] found : cont.value.type (with underlying type _$2)
[error] required: _$2
[error] Note: implicit method impl is not applicable here because it comes after the application point and it lacks an explicit result type
[error] Some(cont.value)
[error] ^
[error] test.scala:130: could not find implicit value for parameter e: Algo[Container[ElementWithId]]
[error] implicitly[Algo[Container[ElementWithId]]].algo(new Container[ElementWithId] {
[error] ^
[warn] test.scala:124: inferred existential type $anon forSome { type $anon <: Algo[C]{def algo(cont: C): Option[_$2]}; type _$2 <: Id }, which cannot be expressed by wildcards, should be enabled
[warn] by making the implicit value language.existentials visible.
[warn] This can be achieved by adding the import clause 'import scala.language.existentials'
[warn] or by setting the compiler option -language:existentials.
[warn] See the Scala docs for value scala.language.existentials for a discussion
[warn] why the feature should be explicitly enabled.
[warn] implicit def impl[C <: Container[_ <: Id]] = new Algo[C] {
[warn] ^
[warn] one warning found
[error] two errors found
[error] (Ducktank/compile:compile) Compilation failed
[error] Total time: 1 s, completed 25.04.2013 23:22:17
更新
提供的解决方案解决了上述问题,但我忘记指定要求 - 对此我深表歉意。我希望 Algo 独立于容器的种类。有了现在的答案,我必须知道容器类型的类型边界(即 T <: Element),然后基本上添加 Algo 需要的类型边界(即 T <: Id) . 但我想保持它足够具体,它可以在具有不同类型边界的容器上工作(例如,Container[T <: SomeOtherElement],而不是 Container[T <: Element])。这在某种程度上可能吗?