As @cchantep mentioned in his comment, self : T
in this case is a self type annotation basically saying that an instance of Foo[T]
needs also to behave as a T
. You can see that is indeed the case in FooImpl
, as FooImpl <: Foo
.
You can find out more about self type annotation here, here or here. Notice how, most of the times, you will see it used in the context of Dependency Injection and the Cake Pattern.
Most interesting from the second link is I think the initial section:
In other words, what is the point of doing this:
trait A
trait B { this: A => }
when you could instead just do this:
trait A
trait B extends A
Why should you use [this syntax]?
[...] the answer generally comes down to "B requiring A" (annotations) vs "B being an A" (inheritance) and that the former is better for dependency management.
Finally, and just to clarify, note that the word self
is not necessary at all. This could be any valid variable name, but self
or this
are most of the time as a convention. That is, you could be doing:
trait A
trait B { myVar: A => }
but that would be less common.