Stanley
Stanley

Reputation: 2816

how to define upper bounds for scala method

how do you define a Scala method such that it would take in the subclass of any type A without throwing a compilation error?

trait A
case class B extends A
case class C extends A
case class W[T](abc: Option[T]= None)

def methodOne(a: A): W[A] = {
  a match {
     case b:B => methodTwo() // throws compilation error
     case c:C => methodThree() // throws compilation error
  } 
}
def methodTwo(): W[B] = y
def methodThree(): W[C] = z

Have tried something like

def methodOne[T <: A](a: A): W[T]

but it doesn't allow to compile still

Upvotes: 2

Views: 52

Answers (2)

Yuval Itzchakov
Yuval Itzchakov

Reputation: 149538

If you want forall T <: A to imply W[T] <: W[A], you need to make W covariant:

case class W[+T](abc: Option[T] = None)

object X {
  def methodOne(a: A): W[A] = {
    a match {
      case b: B => methodTwo()
      case c: C => methodThree()
    }
  }

  def methodTwo(): W[B] = ???
  def methodThree(): W[C] = ???
}

For basic coverage of variance, see this post.

Upvotes: 2

Luka Jacobowitz
Luka Jacobowitz

Reputation: 23512

You need to make W covariant. You can do this easily by defining it as W[+T]:

case class W[+T](abc: Option[T] = None)

This way if B is a subtype of A, W[B] is also a subtype of W[A].

Option for example is defined as Option[+T], therefore Option[B] is a subtype of Option[A].

You can checkout the official scala docs for more details

Upvotes: 2

Related Questions