Карта с зависимым от пути типом значения?
Я знаю, что у Scala есть пути-зависимые типы, поэтому, например, если у меня есть класс во внутреннем классе, я могу ограничить один аргумент метода в качестве экземпляра внутреннего класса другого аргумента:
class Outer { class Inner( x:Int ) }
val o1 = new Outer
val o2 = new Outer
val i11 = new o1.Inner(11)
val i12 = new o1.Inner(12)
val i21 = new o2.Inner(21)
def f[ A <: Outer ]( a:A )( i:a.Inner ) = (a,i)
f(o1)(i11) // works
f(o1)(i21) // type mismatch; i21 is from o2, not o1
И я могу создать карту от внешнего к внутреннему, используя проекцию типа:
var m = Map[Outer,Outer#Inner]()
Но это позволило бы записи, как o1 -> i21
и я не хочу, чтобы это было разрешено. Есть ли какой-нибудь тип магии, требующий, чтобы значение было экземпляром внутреннего класса его ключа? То есть я хочу сказать что-то вроде
var m = Map[Outer,$1.Inner]() // this doesn't work, of course
1 ответ
Нет.
Зависимые от пути типы ограничены областью объекта, как в приведенном вами примере:
def f[ A <: Outer ]( a:A )( i:a.Inner ) = (a,i)
Здесь зависимый от пути тип опирается на ссылку на объект "a", которая находится в области действия для объявления второго списка параметров.
Определение карты выглядит примерно так:
trait Map[A,+B] {
def get(key: A): Option[B]
def + [B1 >: B](kv: (A, B1)): This
}
Там нет объекта типа A
в области здесь для вас, чтобы ссылаться при определении B
,
Как уже говорили другие, вы можете определить новый подобный класс Map, который соответствует этому требованию:
trait Map2[A <: Outer] {
def get(key: A): Option[key.Inner]
def put(key: A)(value: key.Inner): this.type
}