【问题标题】:Scala type inference when mixing type member and type parameter混合类型成员和类型参数时的 Scala 类型推断
【发布时间】:2012-02-07 22:35:19
【问题描述】:

我有以下定义:

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 也有帮助。还有其他构造吗?

【问题讨论】:

  • X[_] 表示X[Any]。特别是,您的映射不会通过 Xode 类型构造函数的通配符参数将值类型与键类型相关联。此外,在put 中,scalac 可以根据需要将A 的类型扩大到Xode[Any]。免责声明:我不是 100% 确定我在写什么;)
  • 是的,我不太关心Map(它的类型无法表达我想要的,这就是我隐藏它的原因),但希望put 能够正常运行。跨度>

标签: scala type-inference


【解决方案1】:

一些(可能解释有点错误)

X[_] 表示X[Any]。特别是,您的映射不会通过 Xode 类型构造函数的通配符参数将值类型与键类型相关联。此外在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    
  }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多