case class Apple(id: String) extends Fruit
type T <: Fruit
val t: T = Apple("apple") // why doesn't the compiler coerce Apple to T?
val t: T = Apple("apple").asInstanceOf[T] // works!
Let's simplify this a bit. Replce T with Pear and Fruit with Fetus.
trait Fetus class Apple extends Fetus type Pear <: Fetus val t: Pear = new Apple()
We declared Fetus, then we said "Apple is Fetus" and then "Pear is Fetus". Our logic is correct so far. But then we try to "put the apple into the box for pears". And here is our mistake.
Let's consider another example:
trait Fetus class Apple extends Fetus type Fruit >: Apple <: Fetus val t: Fruit = new Apple()
Here we declared Fetus, then we said "Apple is Fetus" and then we said that "Fruit is something in the middle between Apple and Fetus". In another words we built following hierarchy: Fetus -> Fruit -> Apple. So, now Apple is subtype of Fruit and you can "put apples into the box for fruit".
Pear definitely cannot be and
Apple, like a Cat cannot be a Dog in spite of they both are animals. You can go by hierarchy only vertically but not horizontally:
Creature | Animal _|_ / \ Dog Cat \ White Cat