混合类型成员和类型参数时的Scala类型推断

时间:2012-01-11 15:06:01

标签: scala type-inference

我有以下定义:

trait Xode[+R] {
  type S = Option[R]
}
case class AXode(a: Int) extends Xode[Int]
case class BXode(b: String) extends Xode[String]

object xtore {
  private var m: Map[Xode[_], Xode[_]#S] = Map()

  def put[A <: Xode[_]](k: A)(v: A#S) {
    m += k -> v    
  }  
}

执行以下操作时,不会引发错误,但我希望AXode#S为Option [Int]。

xtore.put(AXode(5))(Some("apples")) // <-- no error

可能会发生A被推断为Xode[_],然后Xode[_]#S变为Option[_]。我可以用类型参数表达我的意图吗?

当R是抽象类型成员而不是类型参数实现时,它按预期工作。或依赖方法类型和键入v: k.S也有帮助。还有其他构造吗?

1 个答案:

答案 0 :(得分:1)

一些(可能稍微错误的解释)

X[_]表示X[Any]。特别是,您的映射不会将值类型与Xode类型构造函数的wild-carded参数上的键类型相关联。此外,在put中,如果需要,scalac可以将A的类型扩展为Xode[Any]。免责声明:我不是100%肯定我在写什么

传递问题的代码

以下内容拒绝xtore.put(AXode(5))(Some("apples"))并接受xtore.put(AXode(5))(Some(0))。请注意,您还需要捕获Xode的类型参数,而不是OP中的Xode[_]版本。我完全不理解它,可能有一个更简单的解决方案。

  def put[A,B[X] <: Xode[X]](k: B[A])(v: B[A]#S) {
    m += k -> v    
  }