2016-05-25 4 views
2
trait Account[T <: Account[T]] 

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

Описание и описание функций ниже.Scala F-Bounded Type Polymorphism

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

Но ниже вызова выдается сообщение об ошибке.

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

Ошибка

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)))

Может кто-то пожалуйста, объясните мне, почему ошибка компиляции происходит в последнем случае?

ответ

3

Ключом к проблеме является дисперсия - вы пытаетесь вернуть контравариантное значение в ковариантном положении (возвращаемый тип функции). Несмотря List типа ковариантен в качестве аргумента (trait List[+A]), это по существу означает его значение контравариантно (может быть назначен Списком супертипов):

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

Что вы пытаетесь вернуться из функции foo2 является полная противоположность - List[_ <: Account[_]], поэтому ошибка компилятора.

Если вместо List вы используете Set там, который является инвариантным по своему параметру типа, как Array, все будет работать нормально.

+0

Как может компилироваться ниже строка? foo2 (Список [T forSome {type T <: Account [T]}] (BrokerAccount (100), SavingsAccount (50))) –

+0

Для получения дополнительной информации: http://stackoverflow.com/questions/6684493/why-are- массивы-инвариантные-но-списки-ковариантные –

+1

Спасибо Сергею. –