Java : 型宣言についてさらにつっこむ with covariant/contravariant

http://d.hatena.ne.jp/lethevert/20080308/p1
参考リンク)

前回の話を、covariant/contravariantの話を絡めると、もうちょっと整理することができるので、せっかくだからその話を。(covariant/contravariantについては知っていること前提で。知らなければsubtype / covariant / contravariantとかを見るとよいかも)

f :: A -> B

という関数について、「Aは汎用的に、Bは特化的に型を決めるとよい」というのが前回提示した原則だったわけですが、subtypingを考える上で、BはcovariantでAはcontravariantなので、「Aは汎用的に、Bは特化的に」というのは、「f全体として、できるだけ特化的に」という方針だと考えることができます。
このルールを知っていれば、

g :: (A -> B) -> (C -> D)

という関数の型付けを考える場合、

  • A : 特化的に
  • B : 汎用的に
  • C : 汎用的に
  • D : 特化的に

というように機械的に型付けを決めることができます。