Я хотел бы использовать систему типов Scala для ограничения операций в системе, где есть версионные ссылки на некоторые значения. Все это происходит в некотором транзакционном контексте Ctx
, к которому привязан тип версии V
. Теперь есть Factory
для создания ссылочных переменных. Они создаются с прикрепленной к ним версией создания (параметр типа V1
), соответствующей версии контекста, в котором была вызвана фабрика.
Теперь представьте, что какой-то код пытается для доступа к этой ссылке в более поздней версии, которая использует другой Ctx
. Чего я хочу добиться, так это запрета доступа к Ref
в любой версии (поле типа Ctx
V
), которое не соответствует версия создания, но вам разрешено разрешать ссылку с помощью некоторого механизма подстановки, который возвращает новое представление Ref
, к которому можно получить доступ в текущей версии. (это нормально, если замена
вызывается с недопустимым контекстом, например тот, который старше, чем 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
с любым Ctx
, только с тем, версия которого совпадает с версией справочника.
Предпочтительно без структурной типизации или чего-либо, что вызывает проблемы с производительностью.