В более раннем посте SO я спросил, как создать шаблон Aux с типом с более высоким родом ( здесь , у которого был отличный ответ!). Теперь, основываясь на ответе, я пытаюсь продвинуть абстракцию немного, но дальше и сделать вывод о фактическом универсальном параметре из типа аргумента. Проблема в том, что, кажется, возникают проблемы с дифференциацией X
от X.type
. Вот мой код:
// The are types that I want to convert to various things
sealed trait ConversionType
trait CaseA extends ConversionType
object CaseA extends CaseA // In this case, convert to an optional
trait CaseB extends ConversionType
object CaseB extends CaseB // In this case, convert to a future etc...
trait Converter[Prefix] {
type Paramd[_]
def create[N](n:N): Paramd[N]
}
// Create the mechanism to convert from the cases, only doing case A for now...
object Converter {
type Aux[Prefix, Ret[_]] = Converter[Prefix] { type Paramd[N] = Ret[N] }
// Shouldn't `Prefix` be automatically inferred?
def apply[Prefix](prefix:Prefix)(implicit p:Converter[Prefix]): Aux[Prefix, p.Paramd] = p
implicit def makeOptionParamd: Aux[CaseA, Option] =
new Converter[CaseA] {
type Paramd[N] = Option[N]
override def create[N](n:N): Paramd[N] = Option[N](n)
}
}
// This works
val v = Converter.apply[CaseA](CaseA).create("test")
// **** This breaks! Why? ****
val vv = Converter.apply(CaseA).create("test")
В пунктирной строке выше встречаются следующие ошибки:
Error:(135, 29) could not find implicit value for parameter p: Test.this.Converter[Test.this.CaseA.type]
val vv = Converter.apply(CaseA).create("test")
Error:(135, 29) not enough arguments for method apply: (implicit p: Test.this.Converter[SchemaMaker.this.CaseA.type])Test.this.Converter.Aux[SchemaMaker.this.CaseA.type,p.Paramd] in object Converter.
Unspecified value parameter p.
val vv = Converter.apply(CaseA).create("test")
То есть компилятор не связывает точки между объектом CaseA
и типом CaseA
? Есть ли способ исправить это?