Orar Orar - 4 months ago 29
Scala Question

Scala - Overriding trait method using a sub context bound method


sealed trait User {...}
sealed trait Trader extends User {...}

trait AuthObject

trait AuthUserObject {
def authorize[U <: User](u: U): Boolean

trait AuthTraderObject extends AuthUserObject {
def authorize[T <: Trader](t: T): Boolean

object HasPaidTax extends AuthTraderObject {
def authorize[T <: Trader](t: T): Boolean = t.hasPaidTax

This doesnt build. Error:

Error:(15, 7) overriding method authorize in trait AuthUserObject of type [U <: users.User](u: U)Boolean;
method authorize has incompatible type
def authorize[T <: Trader](t: T): Boolean

I need to restrict
user since only trader pays tax. Please, how is this override possible?


First, you should understand the reason for the error: since HasPaidTax extends AuthUserObject, you can ascribe this type to it:

val auth: AuthUserObject = HasPaidTax

But for any auth: AuthUserObject and user: User, you can call auth.authorize(user). So when overriding methods, you can't narrow the argument types or type bounds.

For the solution, you can go with pamu's answer or just move the type parameter to the type (should be equivalent for this case):

trait AuthUserObject[U <: User] {
    def authorize(u: U): Boolean

trait AuthTraderObject[T <: Trader] extends AuthUserObject[T] {
    def authorize(t: T): Boolean

object HasPaidTax extends AuthTraderObject[Trader] {
    def authorize(t: Trader): Boolean = t.hasPaidTax