型推論の実装


91

ここでは、静的型付けと動的型付けについて興味深い議論がいくつかあります。コンパイル型チェック、ドキュメント化されたコードなどにより、私は一般に静的型付けを好みます。しかし、たとえばJavaのようにコードを整理すると、コードが乱雑になることに同意します。

だから私は自分の関数型言語を作り始めようとしています。型推論は実装したいことの1つです。私はそれが大きな主題であることを理解しています、そして私は以前に行われていない何かを作成しようとしているのではなく、基本的な推論だけをしています...

これで私を助けるであろう何を読むべきかについてのポインタ?より理論的なカテゴリー理論/タイプ理論のテキストとは対照的に、より実用的/実用的なものが好ましい。データ構造/アルゴリズムを使用した実装に関するディスカッションテキストがある場合、それはすばらしいことです。


1
まさに私が探していた質問で、いくつかの素晴らしい答えがあります!
ポールホリングスワース

回答:


90

難易度の高い順に、次のリソースが型推論を理解するのに役立ちます。

  1. 自由に利用できる本PLAIの第30章(型推論)、プログラミング言語:アプリケーションと解釈統一ベースの型推論をスケッチしています。
  2. 夏のコースタイプを抽象値として解釈するでは、Haskellをメタ言語として使用して、エレガントなエバリュエーター、タイプチェッカー、タイプ再構成子、推論者を紹介します
  3. 第7章の(種類)ブックEOPLプログラミング言語の要点
  4. 第22章(タイプ復興)ブックTAPLタイプおよびプログラミング言語、および対応するOCamlで実装偵察fullrecon
  5. 新しい本DCPLDesign Concepts in Programming Languagesの第13章(Type Reconstruction)。
  6. 学術論文の選択
  7. クロージャーコンパイラーのTypeInferenceは、型推論へのデータフロー分析アプローチの例です。これは、Hindler Milnerアプローチよりも動的言語に適しています。

ただし、学習するのが最善の方法であるため、プログラミング言語コースの宿題をして、おもちゃの関数型言語の型推論を実装することを強くお勧めします。

MLでアクセスできるこれらの2つの宿題をお勧めします。どちらも1日足らずで完了できます。

  1. ウォームアップするPCFインタープリターソリューション)。
  2. Hindley-Milner型推論のアルゴリズムWを実装するPCF型推論ソリューション)。

これらの課題は、より高度なコースからのものです。

  1. MiniMLの実装

  2. 多態性、存在性、再帰型(PDF)

  3. 双方向型チェック(PDF)

  4. サブタイピングとオブジェクト(PDF)


2
それは私だけですか、それともPLAIの説明はほとんど正しくない/不完全ですか?講義はそれに少し追加しますが、それでもそれを機能させるには十分ではないようです。
宮坂零2013年

PLAIブックの2012年版では、アルゴリズムを取得することもできませんでした。制約リストの代替はありません。代わりに、2003-7バージョンのPLAIブックに型推論アルゴリズムを実装しました。これはよりうまく機能し、let-polymorphismにも適切にスケーリングされるようです。
heykell 2015

28

この件に関する多くの文献が非常に密集しているのは残念です。私もあなたの立場にありました。私はプログラミング言語:アプリケーションと解釈からこのテーマの最初の紹介を得ました

http://www.plai.org/

抽象的アイデアを要約し、その後すぐには明らかにならなかった詳細を説明します。まず、型推論は制約を生成して解決することと考えることができます。制約を生成するには、構文ツリーを再帰して、各ノードに1つ以上の制約を生成します。たとえば、ノードが+演算子の場合、オペランドと結果はすべて数値でなければなりません。関数を適用するノードは、関数の結果と同じタイプになります。

のない言語のlet場合、上記の制約を代入することで盲目的に解決できます。例えば:

(if (= 1 2) 
    1 
    2)

ここでは、ifステートメントの条件はブール値である必要があり、ifステートメントのタイプはthenand else句のタイプと同じであると言えます。私たちは数字であることがわかっ12いるので、代入によって、ifステートメントは数字であることがわかります。

物事が厄介になり、しばらく理解できなかった場合、letを処理します。

(let ((id (lambda (x) x)))
    (id id))

ここでは、id渡されたものを返す関数にバインドしました。これは、識別関数とも呼ばれます。問題は、関数のパラメーターのタイプがのx使用ごとに異なることですid。2番目idはタイプの関数ですa -> aa何でもかまいません。最初のタイプ(a -> a) -> (a -> a)です。これはlet-polymorphismとして知られています。重要なのは、特定の順序で制約を解決することです。最初にの定義の制約を解決しますid。これはになりますa -> a。タイプのその後新鮮な、別のコピーid各場所の制約に置換することができるがid、例えば、使用されるa2 -> a2a3 -> a3

これはオンラインリソースでは簡単に説明されていませんでした。彼らはアルゴリズムWまたはMについて言及しますが、制約の解決の観点からはどのように機能するのか、またはlet-polymorphismでそれができない理由については触れません。これらの各アルゴリズムは制約の解決に順序を強制します。

このリソースは、アルゴリズムW、M、および制約の生成とすべての解決の一般的な概念を結び付けるのに非常に役立つことがわかりました。それは少し密度が高いですが、多くのものより優れています:

http://www.cs.uu.nl/research/techreps/repo/CS-2002/2002-031.pdf

他にも多くの論文があります。

http://people.cs.uu.nl/bastiaan/papers.html

それがややあいまいな世界を明らかにするのに役立つことを願っています。


7

関数型言語のHindley Milnerに加えて、動的言語の型推論に対するもう1つの一般的なアプローチは、 abstract interpretationです。

抽象解釈の考え方は、具体的な値(1、false、クロージャ)の環境を維持する代わりに、言語用の特別なインタープリターを作成することであり、抽象値、つまり型(int、boolなど)で機能します。それは抽象値についてプログラムを解釈しているので、それが抽象解釈と呼ばれる理由です。

Pysonar2は、Pythonの抽象解釈のエレガントな実装です。GoogleがPythonプロジェクトを分析するために使用します。基本的にvisitor pattern、関連するASTノードに評価呼び出しをディスパッチするために使用します。visitor関数transform は、context現在のノードが評価されるを受け入れ、現在のノードのタイプを返します。



弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.