Why we need >: in defining case class

If Either, Left, Right were invariant the following code would compile

trait Either[E, A] {
  def map[B](f: A => B): Either[E, B] =
    this match {
      case Right(a) => Right(f(a))
      case Left(e) => Left(e)
    }
  def flatMap[B](f: A => Either[E, B]): Either[E, B] =
    this match {
      case Left(e) => Left(e)
      case Right(a) => f(a)
    }
  def orElse(b: => Either[E, A]): Either[E, A] =
    this match {
      case Left(_) => b
      case Right(a) => Right(a)
    }
  def map2[B, C](b: Either[E, B])(f: (A, B) => C): Either[E, C] =
    for { a <- this; b1 <- b } yield f(a,b1)
}
case class Left[E, A](value: E) extends Either[E, A]
case class Right[E, A](value: A) extends Either[E, A]

If you now make Either, Left, Right covariant this code start not to compile with covariant type occurs in contravariant position. One fix is to introduce EE >: E, AA >: A where necessary. Another possible fix would be to define map, flatMap, orElse, map2 as extension methods like it’s done in Shapeless with HList methods to avoid covariance issues.