Artavazd Balayan
Artavazd Balayan

Reputation: 2413

Scala compiler is complaining about type mismatch for generic parameter on method level

Why Scala compiler cannot compile next code :

trait Profile {}
class SomeProfile extends Profile

trait Foo {
  def get[T <: Profile]: Option[T]
}

object Example {
  val foo: Foo = new Foo {
    // This works (but might give runtime exception), but it is not ugly? :)
    def get[T <: Profile]: Option[T] = Some((new SomeProfile).asInstanceOf[T])
  }

  val foo2: Foo = new Foo {
    // This does not compile with type mismatch :(
    def get[T <: Profile]: Option[T] = Some(new SomeProfile)
  }
}

Compiler says:

type mismatch;
 found   : Playground.this.SomeProfile
 required: T

But SomeProfile is T, no?

Update:

I want to implement this trait DatabaseConfigProvider with exact type and do it in this way:

val dc: DatabaseConfig[JdbcProfile] = ???
val prov = new DatabaseConfigProvider {
  def get[P <: BasicProfile] = dc.asInstanceOf[DatabaseConfig[P]]
}

which looks ugly because of asInstanceOf.

Upvotes: 2

Views: 1084

Answers (2)

Evgeny
Evgeny

Reputation: 1770

Output type of your method get is defined by caller. You added type bounds (as T <: Profile) but this does only mean limitations for caller. Any casts (as you did) will fail at runtime if caller ask for another subtype of Profile than one you casted.

If you provide more details on what you expect to get as result, I can extend answer with specific advise how to get it.

Upvotes: 1

tmucha
tmucha

Reputation: 709

You wrongly declared input argument. Try below:

trait Profile {}
class SomeProfile() extends Profile

trait Foo {
  def get[T >: Profile]: Option[T]
}

object Example {
  val foo2: Foo = new Foo {
    override def get[T >: Profile]: Option[T] = Some(new SomeProfile())
  }
}

Explanation for what :> does, you could find easily in Stackoverflow (e.g.: What does [B >: A] do in Scala?)

Upvotes: 2

Related Questions