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
这不起作用