双方向型検査

型検査を、型を与えられて検証する「検査(checking)」と、式から型を割り出す「合成(synthesis)」の2モードに分けて規則を設計する手法。Γ ⊢ e ⇐ A(A をチェック)と Γ ⊢ e ⇒ A(A を合成)の2判断を使い分ける。

なぜ分けるのか

完全な型推論(Hindley–Milner)は、依存型・部分型・高ランク多相といった表現力の高い体系では決定不能・困難になる。双方向型検査は「要所に型注釈を要求する」代わりに、これらの体系でも実装しやすく・エラーが局所的になる。注釈の置き場所も原理的に決まる。

規則の向き

モード判断向くもの
検査 (check)e ⇐ A(A は入力)導入規則:λ抽象、コンストラクタ、if の枝
合成 (synth)e ⇒ A(A は出力)変数、関数適用、注釈付き式

導出規則の例

判断は2本:Γ ⊢ e ⇐ A(A は入力=検査)と Γ ⊢ e ⇒ A(A は出力=合成)。各規則は「前提 ⟹ 結論」で読む。

例1: 関数の導入(検査)と適用(合成)

規則前提結論
⇐λΓ, x:A ⊢ e ⇐ BΓ ⊢ λx. e ⇐ A → B
⇒appΓ ⊢ f ⇒ A → B、Γ ⊢ x ⇐ AΓ ⊢ f x ⇒ B

例2: 切替点(注釈と subsumption)

規則前提結論
⇒⇐subΓ ⊢ e ⇒ A、A = BΓ ⊢ e ⇐ B
⇐⇒annoΓ ⊢ e ⇐ AΓ ⊢ (e : A) ⇒ A

採用例

依存型言語のコア(Agda / Idris / Lean)、TypeScript の contextual typing、多くのモダン型検査器。出典は Pierce & Turner “Local Type Inference” (2000)、Dunfield & Krishnaswami のチュートリアル “Bidirectional Typing” (2021)。

押さえどころ(カード化候補)

関連

Graph