# 星之一角

What have you found for these years?

## 2010-05-02

### scala type system (1) covariance and contravariance

covariance and contravariance

Animal animal = new Cat();

type (Cat). 就是假設這邊我們可以寫:

A a = new B();

Scala 裡則很明確告訴你有這樣東西。我們可以簡單歸納成，

animal = Cat.new

val animal:Animal = Cat()

-

Animal popup(){ return new Dog(); }
Cat popup(){ return new Cat(); }

class Ground{ Animal popup(); }
class Grass extends Ground{ Cat popup(); }

Animal animal = ground.popup();

Cat cat = grass.popup();

-

pointer/reference/variable, 他可以指向 list of cat 嗎？

ArrayList<Animal> animals = new ArrayList<Cat>();
animals.get(0).sleep();

ArrayList<Animal> animals = new ArrayList<Cat>();

class List[+T]

Cat < Animal, 因此 List[Cat] < List[Animal],

val animals: List[Animal] = List[Cat]()

Something[U] < Something[T]

-

1. LHS, left hand side (等號左邊)
2. overriding method return type
3. type parameter (generic)

contravariance 比較少見，大概只有上面的 2~3 這兩個例子，

2. overriding method parameter type
3. type parameter (generic)

AnimalUtil:
Int mood(Cat cat){ return cat.life() + cat.mana(); }

DerivedAnimalUtil:
Int mood(Animal animal){ return animal.life(); }

virtual function:

AnimalUtil util = new DerivedAnimalUtil();
util.mood(cat);

mood, 其 parameter type 是 Animal, 那麼就只是在做這件事而已:

Animal animal = cat;

Function1 的定義是 Function1[-T, +R].

AnimalUtil:
Int mood(Animal animal){ return animal.life(); }

DerivedAnimalUtil:
Int mood(Cat cat){ return cat.life() + cat.mana(); }

AnimalUtil util = new DerivedAnimalUtil();
util.mood(new Dog()); // BOOM!!

-

Function1[-T, +R]

val f: Function1[Null, Any] = (any: Any) => null
f(null) // => null

T 的 parameter type 是 PT (Null)
U 的 parameter type 是 PU (Any)
T 的 return type 是 RT (Any)
U 的 return type 是 RU (Null)

U <= T
PU >= PT
RU <= RT

Function1[Any, Null] <= Function1[Null, Any]
Any >= Null
Null <= Any

Function1[Null, Any] 的 subclass.
parameter type 變小了，而 return type 則變大了。

f 是一個只能吃一個 null 的 function, 他會回傳 any

f(null)

null.isInstanceOf[String] // => false

null.asInstanceOf[String] // a String, but the value is null

-

[全劇終]