Я хотел бы использовать систему типов Scala для ограничения операций в системе, где есть версионные ссылки на некоторые значения.Все это происходит в некотором транзакционном контексте Ctx
, к которому прикреплен тип версии V
.Теперь есть Factory
для создания ссылочных переменных.Они создаются с прикрепленной к ним версией creation (параметр типа V1
), соответствующей версии контекста, в котором была вызвана фабрика.
Теперь представьте, что некоторый код пытаетсяполучить доступ к этой ссылке в более поздней версии, которая использует другую Ctx
.Чего я хочу добиться, так это того, что запрещено вызывать доступ к этому Ref
в любой версии (Ctx
* type * field type), которая не соответствует версии создания, но вам разрешено разрешатьссылка на некоторый механизм замещения, который возвращает новое представление Ref
, к которому можно получить доступ в текущей версии.(это нормально, если substitute
вызывается с недопустимым контекстом, например, тот, который старше Ref
V1
- в этом случае может быть выдано исключение времени выполнения)
Вот мойпопытка:
trait Version
trait Ctx {
type V <: Version
}
object Ref {
implicit def access[C <: Ctx, R, T](r: R)(implicit c: C, view: R => Ref[C#V, T]): T =
view(r).access(c)
implicit def substitute[C <: Ctx, T](r: Ref[_ <: Version, T])
(implicit c: C): Ref[C#V, T] = r.substitute(c)
}
trait Ref[V1 <: Version, T] {
def access(implicit c: { type V = V1 }): T // ???
def substitute[C <: Ctx](implicit c: C): Ref[C#V, T]
}
trait Factory {
def makeRef[C <: Ctx, T](init: T)(implicit c: C): Ref[C#V, T]
}
И проблема в том, чтобы определить метод класса access
таким образом, чтобы все это компилировалось, то есть составной объект access
должен компилироваться, но в то же время, которое я не могу вызватьэтот метод класса access
с any Ctx
, только с тем, чья версия соответствует версии справочника.
Желательно без структурной типизации или чего-либо, что вызывает проблемы с производительностью.