: 再帰的データ型 : 型推論 : 陰に型付けされた多相言語
Generalization と instantiation
- function
を変換する場合,自由メタ変数を持つ型 で終了する.型
は
のようになる.
は,
からは instantiate しないとする.
- そのような場合は,以下のように generalize する.
そのため,関数
はすべての型を適用することができる.
- しかし,注意が必要である.以下のプログラムを考えよう.
function randomzap(x) =
let function f(y)=if random() then y else x
in f
end
randomzap の型チェックをする場合, let 式に対して, transexp (これは,
の宣言に対して型チェック) を再帰的に呼び出す 必要がある.
- この位置では
における
の型は
である.しかし generalize できない.
は,勝手な型を引数として持つことはできない.
と同じ型の 引数でなければならない.
- この位置では
は (すでに)
の型の記述として,
現在の環境
に出現する. 従って generalize のアルゴリズムは,以下のようになる.
に出現するメタ変数を
とする.
しかし,
に出現しない場合,
(
を検索する場合,メタ変数は
を検索する
ことにより解釈しなければならない)
for
to
let
return Poly
- すべての関数は Poly 型で与えられる.単相関数も Poly
となる.
- generalization の反対は instantiation である. 多相変数が使われた場合,束縛された型変数をメタ変数に置換する.
( Poly
)=
to
return
- 多相関数を使うところ各々で, instantiation を処理しなけれ ばならない.
- ある呼ぶ側では,束縛変数
はメタ変数
( int に
される) に置換される.
- 別の呼ぶ側では
はメタ変数
( string に
される) に置換される.
- またある呼び側では,全ての
の使用に対して,お互いに一致 していなければならない.例えば randomzap 関数は, 多相型 poly<a> a->(a->a) を持つ.以下のように使われる.
let var i0 := randomzap(0)
var s0 := randomzap("zero")
in i0(3)+size(s0("three"))
end
これは以下のどれかを返す.
,
,
,
.
- randomzap の最初の出現では
(
はメタ変数) と instantiate する.
- しかし,すべての
は
されなければならない. randomzap(0) の型チェックの場合は
を int に
する.
- i0(3) の型チェックの場合 は,
を int に
する.しかし,
は既に int に instantiate されているので,ここでは
が 一貫して使われているか,がチェックされる.
- それから i0(3)+
の型チェックをする場合には,
は再び int に unify される.
- 同様に randomzap の第 2 の出現では,
と instantiate され,
は,すべて string に
される( size の引数として "zero", "three" である).
更新可能変数
: 再帰的データ型 : 型推論 : 陰に型付けされた多相言語
平成12年8月22日