22 / 42
2.1 実際にやってみよう
● 文脈(=変数・関数名とその型の辞書)と
推論規則(=制約を生成するルール)を用意する
– 文脈:
●
+ は int 型 2 つを取って int 型を返す
( +: int → int → int )
– 推論規則:
● 整数リテラル 0,1,2... は int 型
● 文脈に関数 f: a → b, 値 x: a があるとき
関数適用 f x は b 型
● etc...
Slide 23
Slide 23 text
23 / 42
2.1 実際にやってみよう
● コード中の未知の型変数を文脈に追加し,推論規則
を用いて型の等値制約(≒型の等式)を生成する
let-function add_two x = + x 2
制約
文脈
+ : int → int → int
※ 未知の関数・変数に対して,他と重複
しないように型変数を生成し,文脈に追加する
Slide 24
Slide 24 text
24 / 42
2.1 実際にやってみよう
● コード中の未知の型変数を文脈に追加し,推論規則
を用いて型の等値制約(≒型の等式)を生成する
let-function add_two x = + x 2
制約
文脈
+ : int → int → int,
add_two : a → b
※ 未知の関数・変数に対して,他と重複
しないように型変数を生成し,文脈に追加する
Slide 25
Slide 25 text
25 / 42
2.1 実際にやってみよう
● コード中の未知の型変数を文脈に追加し,推論規則
を用いて型の等値制約(≒型の等式)を生成する
let-function add_two x = + x 2
制約
文脈
+ : int → int → int,
add_two : a → b, x : c
※ 未知の関数・変数に対して,他と重複
しないように型変数を生成し,文脈に追加する
Slide 26
Slide 26 text
26 / 42
2.1 実際にやってみよう
● コード中の未知の型変数を文脈に追加し,推論規則
を用いて型の等値制約(≒型の等式)を生成する
let-function add_two x = + x 2
制約
a = c
文脈
+ : int → int → int,
add_two : a → b, x : c
Slide 27
Slide 27 text
27 / 42
2.1 実際にやってみよう
● コード中の未知の型変数を文脈に追加し,推論規則
を用いて型の等値制約(≒型の等式)を生成する
let-function add_two x = + x 2
制約
a = c, c = int
文脈
+ : int → int → int,
add_two : a → b, x : c
Slide 28
Slide 28 text
28 / 42
2.1 実際にやってみよう
● コード中の未知の型変数を文脈に追加し,推論規則
を用いて型の等値制約(≒型の等式)を生成する
let-function add_two x = + x 2
制約
a = c, c = int, int = int
文脈
+ : int → int → int,
add_two : a → b, x : c
Slide 29
Slide 29 text
29 / 42
2.1 実際にやってみよう
● コード中の未知の型変数を文脈に追加し,推論規則
を用いて型の等値制約(≒型の等式)を生成する
let-function add_two x = + x 2
制約
a = c, c = int, int = int, b = int
文脈
+ : int → int → int,
add_two : a → b, x : c
Slide 30
Slide 30 text
30 / 42
2.1 実際にやってみよう
● 得られた制約列を単一化して,文脈に追加した
型変数を消す(≒型の連立方程式の解を求める)
let-function add_two x = + x 2
制約
a = c, c = int, int = int, b = int
文脈
+ : int → int → int,
add_two : a → b, x : c
Slide 31
Slide 31 text
31 / 42
2.1 実際にやってみよう
● 得られた制約列を単一化して,文脈に追加した
型変数を消す(≒型の連立方程式の解を求める)
let-function add_two x = + x 2
制約
a = int, b = int, c = int
文脈
+ : int → int → int,
add_two : a → b, x : c
Slide 32
Slide 32 text
32 / 42
2.1 実際にやってみよう
● 得られた制約列を単一化して,文脈に追加した
型変数を消す(≒型の連立方程式の解を求める)
let-function add_two x = + x 2
制約
a = int, b = int, c = int
文脈
+ : int → int → int,
add_two : a → b, x : c
Slide 33
Slide 33 text
33 / 42
2.1 実際にやってみよう
● 得られた制約列を単一化して,文脈に追加した
型変数を消す(≒型の連立方程式の解を求める)
let-function add_two x = + x 2
制約
文脈
+ : int → int → int,
add_two : int → int, x : int
Slide 34
Slide 34 text
34 / 42
2.1 実際にやってみよう
● 必要な結果を文脈に残して次のコードに進む
( 実装上は,スコープの中に入る前に文脈のバックアップを取り,
結果のうちスコープの外に出るものだけを外側の文脈に追加する )
制約
文脈
+ : int → int → int,
add_two : int → int, x : int
↓ ローカル変数(引数)
Slide 35
Slide 35 text
35 / 42
2.1 実際にやってみよう
● 必要な結果を文脈に残して次のコードに進む
( 実装上は,スコープの中に入る前に文脈のバックアップを取り,
結果のうちスコープの外に出るものだけを外側の文脈に追加する )
制約
文脈
+ : int → int → int,
add_two : int → int
Slide 36
Slide 36 text
36 / 42
2.2 Hindley-Milner 型推論
● 例えば
は関数 f がどんな型であっても使えるはず
● このような関数に対して自動的に全称型を付ける(=
ジェネリック型にする)ように設計された アルゴリ
ズムが Hindley-Milner 型推論
● 中身は先ほど説明した仕組みとほぼ同じで,全称型付
きの関数を文脈に記録する際に工夫をする
let-function apply_twice f x = f (f x)