I would like to use the Scala type system to restrict operations on a system where there are versions that reference some values. All this happens in some kind of transactional context of Ctx , to which version type V is attached. There is now Factory to create reference variables. They are created with the creation version attached to them (enter parameter V1 ) corresponding to the version of the context in which the factory was called.
Now imagine some code trying to access this link in a later version using a different Ctx . I want to make sure that you prohibit access to this type of Ref in any version ( Ctx V type) that does not correspond to the creation version, but it is allowed to allow the link some kind of replacement mechanism that returns a new kind of Ref , which can be accessed in the current version. (this is normal if substitute is called with an invalid context, for example older than Ref V1 - in this case, a runtime exception may be selected)
Here is my attempt:
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] }
And the problem is to define the access class method in such a way that the whole thing is compiled, i.e. the composite access object must compile, but at the same time I cannot call this method of the access class any Ctx , only with a version whose version corresponds to the reference version.
Preferably without structural typing or anything that poses performance problems.
scala type-constraints type-parameter
0__
source share