依赖类型的隐式扩展
Implicit expansion with dependant types
我想知道为什么以下情况不起作用。假设我有两种类型:
trait Def[T]
trait Ref[T]
case class Module()
我想将 Def
转换为 Ref
,因此我声明了以下方法:
object Ref {
implicit def fromDef[A](defin: Def[A])(implicit rc: RefConverter[A]): Ref[rc.ResType] = new Ref[rc.ResType] {}
}
但万一:
val moduleDef: Def[Module] = ???
val moduleRef: Ref[Module] = moduleDef
Scala 编译器无法找到正确的转换方式(即 fromDef
函数),但如果我们明确告诉它使用此转换,即 Ref.fromDef(moduleDef)
,scalac 会找到正确的RefConverter
实例。另一个需要考虑的重要事项是,如果我将结果类型更改为 Ref[A]
,它也会解析转换链。所以编译器无法解析具有依赖结果类型的链?
编译如下:
trait Def[T]
trait Ref[T]
case class Module()
trait RefConverter[T]{
type ResType = T
type RefType = T
}
object Ref {
implicit def fromDef[A](defin: Def[A])(implicit rc: RefConverter[A]): Ref[rc.ResType] = new Ref[rc.RefType] {}
}
implicit val rc = new RefConverter[Module]{}
val d = new Def[Module]{}
val r = d:Ref[Module]
这会编译并打印类型:
object Test extends App {
implicit val rc = new RefConverter[Module] {}
object Ref {
implicit def fromDef[A](defin: Def[A])(implicit rc: RefConverter[A]): Ref[rc.ResType] = new Ref[rc.ResType] {}
}
val moduleDef: Def[Module] = new Def[Module]() {}
val moduleRef: Ref[Module] = moduleDef
println(moduleDef.getClass.getName)
println(moduleRef.getClass.getName)
trait RefConverter[T] {
type ResType = T
}
trait Def[T]
trait Ref[T]
case class Module()
}
我假设您的 Refconverter 不在范围内,或者您被我们的 IDE 强调为错误而误导了。
您必须将类型参数和类型成员绑定在一起。
您可以像其他答案一样提供别名;请注意,它不适用于特征中绑定的类型,请参阅代码注释。
但是你可以提供另一个有界的类型参数:
trait Ref[T]
trait Def[T]
case class Module()
object Ref {
//implicit def fromDef[A](defin: Def[A])(implicit rr: RefResolver[A]): Ref[rr.RefType] = new Ref[rr.RefType] {}
//implicit def fromDef[A](defin: Def[A])(implicit rr: RefResolver[A]): Ref[A] = new Ref[A] {} // OP notes that this works
implicit def fromDef[A, B <: A](defin: Def[A])(implicit rr: RefResolver[B]): Ref[B] = new Ref[B] {}
// or
implicit def fromDef[A](defin: Def[A])(implicit rr: RefResolver[A]): Ref[A] { type RefType <: A } = new Ref[A] { type RefType = A }
}
trait RefResolver[A] {
type RefType
//type RefType <: A // not good enough
}
object RefResolver {
implicit val moduleRes: RefResolver[Module] { type RefType = Module } =
new RefResolver[Module] {
type RefType = Module
}
}
object Test extends App {
val moduleDef: Def[Module] = new Def[Module] {}
val moduleRef: Ref[Module] = moduleDef
}
我想知道为什么以下情况不起作用。假设我有两种类型:
trait Def[T]
trait Ref[T]
case class Module()
我想将 Def
转换为 Ref
,因此我声明了以下方法:
object Ref {
implicit def fromDef[A](defin: Def[A])(implicit rc: RefConverter[A]): Ref[rc.ResType] = new Ref[rc.ResType] {}
}
但万一:
val moduleDef: Def[Module] = ???
val moduleRef: Ref[Module] = moduleDef
Scala 编译器无法找到正确的转换方式(即 fromDef
函数),但如果我们明确告诉它使用此转换,即 Ref.fromDef(moduleDef)
,scalac 会找到正确的RefConverter
实例。另一个需要考虑的重要事项是,如果我将结果类型更改为 Ref[A]
,它也会解析转换链。所以编译器无法解析具有依赖结果类型的链?
编译如下:
trait Def[T]
trait Ref[T]
case class Module()
trait RefConverter[T]{
type ResType = T
type RefType = T
}
object Ref {
implicit def fromDef[A](defin: Def[A])(implicit rc: RefConverter[A]): Ref[rc.ResType] = new Ref[rc.RefType] {}
}
implicit val rc = new RefConverter[Module]{}
val d = new Def[Module]{}
val r = d:Ref[Module]
这会编译并打印类型:
object Test extends App {
implicit val rc = new RefConverter[Module] {}
object Ref {
implicit def fromDef[A](defin: Def[A])(implicit rc: RefConverter[A]): Ref[rc.ResType] = new Ref[rc.ResType] {}
}
val moduleDef: Def[Module] = new Def[Module]() {}
val moduleRef: Ref[Module] = moduleDef
println(moduleDef.getClass.getName)
println(moduleRef.getClass.getName)
trait RefConverter[T] {
type ResType = T
}
trait Def[T]
trait Ref[T]
case class Module()
}
我假设您的 Refconverter 不在范围内,或者您被我们的 IDE 强调为错误而误导了。
您必须将类型参数和类型成员绑定在一起。
您可以像其他答案一样提供别名;请注意,它不适用于特征中绑定的类型,请参阅代码注释。
但是你可以提供另一个有界的类型参数:
trait Ref[T]
trait Def[T]
case class Module()
object Ref {
//implicit def fromDef[A](defin: Def[A])(implicit rr: RefResolver[A]): Ref[rr.RefType] = new Ref[rr.RefType] {}
//implicit def fromDef[A](defin: Def[A])(implicit rr: RefResolver[A]): Ref[A] = new Ref[A] {} // OP notes that this works
implicit def fromDef[A, B <: A](defin: Def[A])(implicit rr: RefResolver[B]): Ref[B] = new Ref[B] {}
// or
implicit def fromDef[A](defin: Def[A])(implicit rr: RefResolver[A]): Ref[A] { type RefType <: A } = new Ref[A] { type RefType = A }
}
trait RefResolver[A] {
type RefType
//type RefType <: A // not good enough
}
object RefResolver {
implicit val moduleRes: RefResolver[Module] { type RefType = Module } =
new RefResolver[Module] {
type RefType = Module
}
}
object Test extends App {
val moduleDef: Def[Module] = new Def[Module] {}
val moduleRef: Ref[Module] = moduleDef
}