Вывод типа Scala при смешивании элемента типа и параметра типа - PullRequest
2 голосов
/ 11 января 2012

У меня есть следующие определения:

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 Ответ

1 голос
/ 11 января 2012

Некоторые (возможно, немного неправильное объяснение)

X[_] означает X[Any].В частности, ваша карта не связывает типы значений с типами ключей, а аргумент с подстановочными знаками - с конструктором типа Xode.Кроме того, в put скаляр может расширить тип с A до Xode[Any], если это необходимо.Отказ от ответственности: я не на 100% уверен в том, что пишу

Код, который передает вопрос

Следующее отклоняет xtore.put(AXode(5))(Some("apples")) и принимает xtore.put(AXode(5))(Some(0)).Обратите внимание, что вам также нужно захватить параметр типа Xode в отличие от версии Xode[_] в OP.Я не совсем понимаю, и может быть более простое решение.

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