Проблема с параметризованным классом case ограниченного типа и args по умолчанию в Scala

Рассмотрим следующее (проверено на Scala 2.8.1 и 2.9.0):

trait Animal
class Dog extends Animal

case class AnimalsList[A <: Animal](list:List[A] = List())
case class AnimalsMap[A <: Animal](map:Map[String,A] = Map())

val dogList = AnimalsList[Dog]()  // Compiles
val dogMap = AnimalsMap[Dog]()    // Does not compile

Последняя строка не работает:

error: type mismatch;
 found   : scala.collection.immutable.Map[Nothing,Nothing]
 required: Map[String,Main.Dog]
Note: Nothing <: String, but trait Map is invariant in type A.
You may wish to investigate a wildcard type such as `_ <: String`. (SLS 3.2.10)
Error occurred in an application involving default arguments.
    val dogMap = AnimalsMap[Dog]()    // Does not compile
                       ^
one error found

Замена на val dogMap = AnimalsMap[Dog](Map()) исправляет это, но больше не использует значение аргумента по умолчанию.

Почему значение по умолчанию определяется как Map[Nothing,Nothing], учитывая, что аналог List работает как ожидалось? Есть ли способ создать экземпляр AnimalsMap, который использует значение по умолчанию для аргумента map?


Edit: Я принял ответ на свой более насущный второй вопрос, но мне все еще интересно узнать, почему тип ключа Map() определяется по-разному в этих двух случаях:

case class AnimalsMap1(map:Map[String,Animal] = Map())
val dogs1 = AnimalsMap1() // Compiles

case class AnimalsMap2[A <: Animal](map:Map[String,A] = Map())
val dogs2 = AnimalsMap2[Dog]() // Does not compile

Edit 2: Похоже, что границы типов не имеют значения - любой параметрический тип класса case вызывает проблему:

case class Map3[A](map:Map[String,A] = Map())
val dogs3 = Map3[Dog]() // Does not compile
7
задан Kristian Domagala 27 May 2011 в 00:40
поделиться