2nd Edition Page 429 - Structural Subtyping
Posted: Mar 30, 2011 6:31 PM
Advertisement
Hi, While trying out the example for structural subtyping on page 429, I came across the following anomaly: class Food abstract class Animal { type SuitableFood <: Food def eat(food:SuitableFood) } class Grass extends Food class Cow extends Animal { type SuitableFood = Grass override def eat(food:Grass) {} } class Meat extends Food class Lion extends Animal { type SuitableFood = Meat override def eat(food: Meat) {} } scala> val leo = new Lion leo: Lion = Lion@284d0371 scala> val molly = new Cow molly: Cow = Cow@6a5c775d scala> val herbs:List[Animal { type SuitableFood = Grass }] = Nil hebs: List[Animal{type SuitableFood = Grass}] = List() scala> molly :: herbs res15: List[Animal{type SuitableFood = Grass}] = List(Cow@6a5c775d) scala> leo :: res15 res16: List[Animal{type SuitableFood >: Grass with Meat <: Food}] = List(Lion@284d0371, Cow@6a5c775d) How am I able to add a Lion (who eats meat) to a List[Animal{type SuitableFood = Grass}] ? Is my assumption that only animals that eat grass should be allowed to the List correct? If I do the above with a mutable list the types work "correctly" and I can't add a Lion to a List[Animal{type SuitableFood = Grass}]: val buf = new ArrayBuffer[Animal {type SuitableFood = Grass}]() buf: scala.collection.mutable.ArrayBuffer[Animal{type SuitableFood = Grass}] = ArrayBuffer() scala> buf += molly res18: buf.type = ArrayBuffer(Cow@6a5c775d) scala> buf += leo <console>:22: error: type mismatch; found : leo.type (with underlying type Lion) required: Animal{type SuitableFood = Grass} buf += leo