Cannot implement view type as a member of type

While I split my head over another question , I came across different puzzles that seem to be related. This is one of them:

trait Sys[S <: Sys[S]] { type Peer <: Sys[Peer] } trait Fenced { type Peer <: Sys[Peer] } def makeFence[S <: Sys[S]] = new Fenced { type Peer = S#Peer } 

If the error is this:

 error: overriding type Peer in trait Fenced with bounds >: Nothing <: Sys[this.Peer]; type Peer has incompatible type def makeFence[S <: Sys[S]] = new Fenced { type Peer = S#Peer } ^ 

Why? (also tried to add _:S => self-tuning to Sys , it didn't matter)


While the Rex answer allows you to build a Fenced object, it really does not solve the problems that I have when a representation type character is lost when using a type projection ( S#Peer ). I came up with another scenario that creates more stringent restrictions; I think this is the main problem:

 trait Test[S <: Sys[S]] { def make[T <: Sys[T]](): Unit make[S#Peer]() } error: type arguments [S#Peer] do not conform to method make type parameter bounds [T <: Sys[T]] make[S#Peer]() ^ 
+8
types scala abstract-type type-projection
source share
2 answers

I'm still not quite sure what limitations you are looking for, but there is one possibility:

 trait Sys[S <: Sys[S]] { type Peer <: Sys[Peer] } trait Fenced { type MySys <: Sys[MySys] type Peer = MySys#Peer } def makeFence[S <: Sys[S]] = new Fenced{ type MySys = S } 

This gives you (and requires!) Access to both Peer and the source external type inside Fenced . I'm not sure if Fenced can do this or abstract from external types.

+3
source share

Can you enter a Sys parameter of covariant type? For example, this compiles:

 trait Sys[+S <: Sys[S]] { type Peer <: Sys[Peer] } trait Fenced { type Peer <: Sys[Peer] } def makeFence[S <: Sys[S]] = new Fenced { type Peer = S#Peer } 

Now, if we have the following (wrapped in an object just for the convenience of copying with a copy of REPL):

 object Example { case class SysX(i: Int) extends Sys[SysX] { type Peer = SysY } case class SysY(j: Int) extends Sys[SysY] { type Peer = SysX } } import Example._ 

It works as I expected:

 scala> val fenceX = makeFence[SysX] fenceX: java.lang.Object with Fenced{type Peer = Example.SysX#Peer} = ... scala> val y: fenceX.Peer = SysY(1) y: fenceX.Peer = SysY(1) scala> val y: fenceX.Peer = SysX(1) <console>:15: error: type mismatch; found : Example.SysX required: fenceX.Peer val y: fenceX.Peer = SysX(1) 

Which (I think) what you want?

+3
source share

All Articles