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

标签 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 并隐式应用它?

最佳答案

两个问题:首先,您的 evidence 参数不是隐式的,因此也没有被编译器隐式地找到:

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,因为如何当 Inner1 是抽象的时,您是否要提供证据证明它的成员 Inner2 等于 Outer1#Inner1?这就是为什么我要求具体的场景,因为从这个抽象的布局中,我不确定你会得到什么。

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

trait Outer1 {
  type Inner1
  def bar: Inner1
}

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

  def foo: Inner2 = outer1.bar
}

关于scala - 为什么隐式转换在这里不起作用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16885057/

相关文章:

scala - Map 不能在 scala 中序列化吗?

unit-testing - 使用哪个 Scala 框架来测试 REST 服务?

c++ - (没有)在数值表达式中使用时隐式转换?

c - C 中的双指针常量正确性警告

c# - 为什么 C# 中的这种隐式类型转换会失败?

c++ - 如何将任何内容隐式转换为字符串?

斯卡拉 : Enumeration with special characters

java - 如何停止由 java 中的 ProcessBuilder 启动的进程

scala - Scala 中的类型推断和泛型

c++ - 在重载决议期间如何处理隐含的对象参数?