2014-09-19 2 views
2
sealed trait Option[+A] 
case object None extends Option[Nothing] 
case class Some[A](get: A) extends Option[A] 

class C1() {} 
class C2() extends C1 {} 
val x1: Some[C1] = Some(new C2)   //> x1 : T.Some[T.C1] = Some([email protected]) 
val x2: Some[C2] = Some(new C2)   //> x2 : T.Some[T.C2] = Some([email protected]) 
// val x3: Some[C1] = x2 // Type mismatch 

Какова цель +A в Some[+A]? Если я определяю его как Some[A], он тоже будет ковариантным, я понимаю, что он наследует ковариацию от Option[A].ковариации в подклассе

ответ

3

Нет, это не так, рассматривать этот случай:

sealed trait Maybe[+A] 
case object Empty extends Maybe[Nothing] 
case class Just[A](x: A) extends Maybe[A] 

scala> val j: Maybe[AnyRef] = Just[String]("Hello") 
j: Maybe[AnyRef] = Just(Hello) 

и это:

scala> val j: Just[AnyRef] = Just[String]("Hello") 
<console>:10: error: type mismatch; 
found : Just[String] 
required: Just[AnyRef] 
Note: String <: AnyRef, but class Just is invariant in type A. 
You may wish to define A as +A instead. (SLS 4.5) 
     val j: Just[AnyRef] = Just[String]("Hello") 

Я понимаю, что объявлять тип переменной, как Some глупо, но я видел такой код.

+0

Отредактировал мой вопрос, что-то странное происходит. Разве это нарушает принцип замещения, или я пропускаю что-то простое? –

+1

@VictorMoroz: в вашем обновлении аннотация типа на 'x1' выводит вывод типа RHS, поэтому' new C2' выводится на тип 'C1'. Поместите параметр типа 'C2' на' Some', и вы получите сообщение об ошибке. –

Смежные вопросы