Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Fixing abstract types in self type

Tags:

types

scala

Consider this:

object TypeProblem {

  trait A {
    type T
    val set = Set[T]()
  }

  trait B {
    def b()
  }

  trait FooBad { this: A =>
    type T <: B
    def x {
      set.foreach(_.b())
    }
  }

  trait FooOk { this: A =>
    type MyT <: B
    type T = MyT

    def x {
      set.foreach(_.b())
    }
  }

}

The compiler complains that value b is not a member of FooBad.this.T So why does FooOk work where I define a new type MyT and assigning T to MyT?

like image 574
Channing Walton Avatar asked Mar 03 '26 02:03

Channing Walton


1 Answers

The self type of FooBad is expanded by the compiler to FooBad with A (so that you can still access the members you define yourself). That means that T gets the definition in A, and not the one in FooBad, as you'd expect. You can fix your code by changing the definition of FooBad to explicitly add your own type:

trait FooBad { this: A with FooBad =>
   ..
}

or even better by using subclassing

trait FooBad extends A {
  ..
}

It is my belief that in most cases self-types should be replaced by plain subclassing. It is simpler to understand, less scary, and leads to better encapsulation.

like image 183
Iulian Dragos Avatar answered Mar 06 '26 00:03

Iulian Dragos



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!