Reputation: 81
I have a trait I
(intermediary), a class M
(mixer) mixing in the trait and a trait S
(specific).
class M extends Something with S {
def baz() = foo()
}
trait I {
def foo(): { ...; bar(); ... }
def bar()
}
trait S extends I {
def bar() = 42
}
I
serves as an intermediate layer between M
and S
, providing a common interface.
I have an implemented method foo
in I
that calls a method bar
(not implemented in I
but defined there). What I would like to achieve is that all traits extending I
must implement bar
, so that this would throw a compile time error because bar
is not implemented:
trait Z extends I
Is this possible in Scala?
P.S.: I am aware of the answer of Force Scala trait to implement a certain method but I do not want that kind of explicit coupling.
Upvotes: 6
Views: 1120
Reputation: 51
I don't know of any way in Scala to force a trait to have concrete implementations for all methods. You could write a macro that generated a small test class and then the compiler would verify that the test class was concrete. It shouldn't be too hard to write a macro that takes this code:
@VerifyAllMethodsConcrete
trait Z extends I { ... }
and transforms it into this code:
trait Z extends I { ... }
class TestClassForVerifyingConcreteMethodsOfZ { }
Now if trait Z
does not override bar()
there will be an early error that says TestClassForVerifyingConcreteMethodsOfZ needs to be abstract
. This error message isn't perfectly clear but hopefully this does the early verification on Z
that you want.
Upvotes: 0
Reputation: 8281
It seems a use case for self types :
trait Z {
self : I =>
}
The compiler will check that any class in a hierarchy including Z
is or extends I
.
Upvotes: 1
Reputation: 751
I thought about structural subtyping:
trait I[T<: { def:foo:Unit}]
....
would that work for you?
Upvotes: 1