Search code examples
scalatype-bounds

Scala abstract type bounds cross referencing


I have two abstract classes which will hold references to each other.How / can I type bound the type members so as the types of HexT in the SideT members of the derived Hex classes will always be the derived Hex class? so for a derived class HexA it is guaranteed that: HexA#SideT#HexT = HexA

And similarly that the types of SideT in the HexT members of all the derived Side classes will be the derived Side Class: SideB#HexT#SideT = SideB

I'm using Scala for Eclipse 2.1.0.M1 with Eclipse 3.7.2 All Classes are in separate files. The following compiles OK but doesn't guarantee what I want:

abstract class Hex { type SideT <: Side {type HexT <= Hex } }
abstract class Side { type HexT <: Hex {type SideT <= side } }
class HexC() extends Hex() { type SideT = SideC }
class SideC extends Side { type HexT = HexC }

But the following won't compile in the derived implementations:

abstract class Hex{type SideT <: Side {type HexT = this.type}}
abstract class Side{type HexT <: Hex {type SideT = this.type}}
class HexC() extends Hex(){
  type SideT = SideC //This won't compile
}
class SideC extends Side {
  type HexT = HexC //this won't compile
}

Is this correct? Should this compile?


Solution

  • How about this?

    abstract class Hex {
      type SideT <: Side
    }
    
    abstract class Side {
      type HexT <: Hex
    }
    
    class HexC extends Hex {
      type SideT = SideC
    }
    
    class SideC extends Side {
      type HexT = HexC
    }
    
    val evidence1 = implicitly[SideC#HexT =:= HexC]
    val evidence2 = implicitly[SideC#HexT#SideT =:= SideC]
    

    Or with an encapsulating trait for the domain:

    trait abstractDomain {
      type SideT <: Side
      type HexT <: Hex
    
      abstract class Hex
      abstract class Side
    }
    
    object domain extends abstractDomain {
      type SideT = SideC
      type HexT = HexC
    
      class HexC extends Hex
      class SideC extends Side
    }
    

    Or with type parameters:

    abstract class Hex[HexT <: Hex[HexT, SideT], SideT <: Side[HexT, SideT]]
    abstract class Side[HexT <: Hex[HexT, SideT], SideT <: Side[HexT, SideT]]
    
    class HexC extends Hex[HexC, SideC]
    class SideC extends Side[HexC, SideC]