为什么隐式转换在这里不起作用?

时间:2013-06-02 16:54:07

标签: scala implicit-conversion

我有这种代码

trait Outer1 {
  type Inner1
}

trait Outer2 {
  type Inner2

  val ev: Outer1#Inner1 =:= Inner2

  def f: Outer1#Inner1
}


object Main {

//  My Problem here  
//  def test1(o2: Outer2): o2.Inner2 =
//    o2.f                                  // <- type mismatch

  def test2(o2: Outer2): o2.Inner2 =
    o2.ev.apply(o2.f)
}

有没有机会让test1工作?为什么Scala编译器无法看到ev并隐式应用它?

1 个答案:

答案 0 :(得分:3)

两个问题:首先,您的证据参数不是隐式的,因此也不会被编译器隐式找到:

trait Outer1 {
  type Inner1
}

trait Outer2 {
  type Inner2

  implicit val ev: Outer1#Inner1 =:= Inner2

  def f: Outer1#Inner1
}

第二个问题,值的成员是not part of the standard implicit lookup scope。所以你需要导入:

object Main {
  def test1(o2: Outer2): o2.Inner2 = {
    import o2.ev  // !
    o2.f
  }
}

编辑:尽管有抽象类型检查,但如果我没弄错的话,你无法实际实现 Outer2,因为你怎么样当Inner2是抽象的时,证明其成员Outer1#Inner1等于Inner1?这就是我要求具体方案的原因,因为从这个抽象的布局来看,我不确定你是否会去任何地方。

据我所知,证据只对依赖类型有意义,例如

trait Outer1 {
  type Inner1
  def bar: Inner1
}

trait Outer2 {
  type Inner2
  val outer1: Outer1 { type Inner1 = Inner2 }

  def foo: Inner2 = outer1.bar
}