tobi
tobi

Reputation: 81

Force trait to implement method

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

Answers (3)

Kevin2342
Kevin2342

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

Yann Moisan
Yann Moisan

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

Stefan Kunze
Stefan Kunze

Reputation: 751

I thought about structural subtyping:

trait I[T<: { def:foo:Unit}]

....

would that work for you?

Upvotes: 1

Related Questions