Scala 依赖类型的隐式扩展
我想知道为什么下面的例子不起作用。假设我有两种类型:Scala 依赖类型的隐式扩展,scala,types,implicit-conversion,Scala,Types,Implicit Conversion,我想知道为什么下面的例子不起作用。假设我有两种类型: 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: D
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中绑定的类型,请参见代码注释 但您可以提供另一个有界的类型param:
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 Ref[T]
性状定义[T]
案例类模块()
对象引用{
//隐式def fromDef[A](定义:def[A])(隐式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注意到这是可行的
隐式def fromDef[A,B#ResType和#RefType有什么区别?Arseniy,我很抱歉,但这只是一个输入错误,只有一个ResType
这是一个很好的解决方案,回答了这个问题,但实际上不是很实际,因为它将依赖类型限制为A
,所以如果我有一个独立类型ModuleId
,并且想要to写入val moduleRef:Ref[ModuleId]=moduleDef
这不起作用