Polymorphic Methodで遊ぶ
自分用メモ。別に面白いことは書いてありません。
# class type c = object method id : 'a.'a -> 'a end;; class type c = object method id : 'a -> 'a end
を考える。idの型に総称量化子がつかないのが気持ち悪い。
# let f x = begin x#id 1; x#id true end;; This expression has type bool but is here used with type int
xの型は多相に推論されないのでダメ。
# let f (x:c) = begin x#id 1; x#id true end;; Warning S: this expression should have type unit. val f : c -> bool = <fun>
xの型をちゃんと宣言してやれば大丈夫。
さて、問題はここから。
# class b = object method f (x:int) = x end;; class b : object method id : int -> int end
を考える。
# f (new b);; This expression has type b but is here used with type c Types for method id are incompatible
ふむ。まあ当然ダメ。これ、どうやってんのかちょっと気になる。推論されたわけではない型は、特殊な処理をしてるんだろうなあ。普通に単一化で取り扱おうとするとめんどくさそうかな。
ついでに。
# f (object method id x = x end);; This expression has type < id : 'a -> 'a > but is here used with type c The universal variable 'b would escape its scope
これもダメか。でもエラーメッセージが違う。どういう意味だろう。
# let id x = x;; val id : 'a -> 'a = <fun> # let a = object method id x = x end;; val a : < id : 'a -> 'a > = <obj> # id (a:>c);; This expression cannot be coerced to type c = < id : 'a. 'a -> 'a >; it has type < id : 'b -> 'b > but is here used with type #c The universal variable 'c would escape its scope
むむ。さっきと同じエラーになった。つまりcoercionできなくてエラーになってるわけだな。しかしエラーの意味が謎。前半はいいとして、最後の「The universal variable 'c would escape its scope」が理解できん。'cってどこから出てきたんだろう。aの型くらいしか他には型変数が出てくるものはないけど…
わかったこと。
- object式の型は一番外に∀がついた多相型
- Polymorphic Methodの型検査は普通の多相型のとは違う
くらい。当たり前ですけど。