Compile time check on some property

后端 未结 2 1998
借酒劲吻你
借酒劲吻你 2021-01-06 19:46

Given the following scala code:

sealed trait Color
case object Red extends Color
case object Blue extends Color

sealed trait Car {
  def isBroken: Boolean
          


        
2条回答
  •  我在风中等你
    2021-01-06 20:03

    I am assuming that you can change your class structure.

    One way to achieve what you want is using Type Level Programming. There is a pretty good stack overflow post on this here: Scala type programming resources

    Here is some sample code based on your original code which demonstrates how this can be achieved using the type system within Scala.

    /* 
     * Color traits I've left the same except converted the objects 
     * to classes. This would work just as well with traits. It might 
     * even be better if the Colors such as Red and Blue are traits
     * themselves that extend Color, I'm still just learning this 
     * method myself.
     */
    sealed trait Color
    class Red extends Color
    class Blue extends Color
    
    /* New trait to represent whether something is broken or not */
    sealed trait IsBroken    
    class Broken extends IsBroken
    class NotBroken extends IsBroken
    
    /* Change Car trait to have two type parameters, broken and color */   
    trait Car[T <: Color, S <: IsBroken]
    
    /* fixBrokenCar signature includes whether a car is broken and it's color */
    def fixBrokenRedCar(c: Car[Red, Broken]): Car[Red, NotBroken]
        = new Car[Red, NotBroken]{}
    
    val brokenRedCar = new Car[Red, Broken]{}
    val fixedRedCar = new Car[Red, NotBroken]{}
    val brokenBlueCar = new Car[Blue, Broken]{}
    
    /* Compiles */
    fixBrokenRedCar(brokenRedCar)
    
    /* Doesn't compile */
    fixBrokenRedCar(fixedRedCar)
    
    /* Doesn't compile */
    fixBrokenRedCar(brokenBlueCar)
    

提交回复
热议问题