2
trait Account[T <: Account[T]]

case class BrokerAccount(total:BigDecimal) extends Account[BrokerAccount]
case class SavingsAccount(total:BigDecimal) extends Account[SavingsAccount]

Below function declaration and invocation works fine.

def foo1( xs: Array[T forSome { type T <: Account[T] }]):Array[T forSome { type T <: Account[T] }] = xs
foo1(Array(BrokerAccount(100),SavingsAccount(50)))

But below invocation gives compilation error.

def foo2( xs: List[T forSome { type T <: Account[T] }]):List[T forSome { type T <: Account[T] }] = xs
foo2(List(BrokerAccount(100),SavingsAccount(50)))

Error

Main.scala:14: error: type mismatch;
found : List[Product with Serializable with Main.Account[_ >: Main.SavingsAccount with Main.BrokerAccount <: Product with Serializable with Main.Account[_ >: Main.SavingsAccount with Main.BrokerAccount <: Product with Serializable]]]
required: List[T forSome { type T <: Main.Account[T] }] foo2(List(BrokerAccount(100),SavingsAccount(50)))

Can someone please explain me why compilation error occur in later case?

Johny T Koshy
  • 3,857
  • 2
  • 23
  • 40
R.M
  • 31
  • 4

1 Answers1

3

The key to the problem is variance - you're trying to return a contravariant value in covariant position (function return type). Despite List type is covariant in its argument (trait List[+A]), this essentially means its values are contravariant (can be assigned to a List of supertypes):

val listOfSupers: List[_ >: Account[_]] = List(BrokerAccount(100), SavingsAccount(50))

What you're trying to return from the function foo2 is a complete contrary - List[_ <: Account[_]], thus the compiler error.

If instead of List you use Set there, which is invariant in its type parameter just like Array, everything will work fine.

Sergey
  • 2,880
  • 3
  • 19
  • 29
  • How can below line compiles then? foo2( List[T forSome { type T <: Account[T] }](BrokerAccount(100),SavingsAccount(50))) – R.M May 25 '16 at 10:46
  • For more details: http://stackoverflow.com/questions/6684493/why-are-arrays-invariant-but-lists-covariant – Al M May 25 '16 at 11:43