web-dev-qa-db-ja.com

型推論の実装

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

それで、私は自分自身の機能的なスタイルの言語を構築し始めようとしています、そして型推論は私が実装したいものの1つです。私はそれが大きな主題であることを理解しています、そして私はこれまで行われていない何かを作成しようとしているのではなく、基本的な推論だけです...

これを手伝ってくれる、何を読むべきかについての指針はありますか?より理論的なカテゴリー理論/タイプ理論のテキストとは対照的に、より実用的/実用的なものが好ましい。データ構造/アルゴリズムを含む実装ディスカッションテキストがそこにあるとしたら、それは素晴らしいことです。

87
deepblue

次のリソースは、型の推論を理解するのに役立ちます。

  1. 自由に利用できる本PLAI)の第30章(型推論プログラミング言語:アプリケーションと解釈、スケッチに基づく型推論。
  2. サマーコース 型を抽象的な値として解釈する は、Haskellをメタ言語として使用する、エレガントな評価者、型チェッカー、型再構築者、推論者を紹介します。
  3. 本EOPLプログラミング言語のエッセンシャルの第7章(タイプ)。
  4. 本TAPL型とプログラミング言語の第22章(型の再構築)、および対応するOCamlの実装 recon および fullrecon
  5. 新しい本DCPLプログラミング言語の設計概念の第13章(型の再構築)。
  6. 学術論文の選択
  7. クロージャーコンパイラの TypeInference は、型推論へのデータフロー分析アプローチの例です。これは、HindlerMilnerがアプローチする動的言語に適しています。

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

MLでこれら2つのアクセシブルな宿題をお勧めします。どちらも、1日以内に完了することができます。

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

これらの割り当て より高度なコースからのものです:

  1. MiniMLの実装

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

  3. 双方向タイプチェック(PDF)

  4. サブタイプとオブジェクト(PDF)

88
namin

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

http://www.plai.org/

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

'let'のない言語の場合、置換によって上記の制約を盲目的に解決できます。例えば:

(if (= 1 2) 
    1 
    2)

ここでは、ifステートメントの条件はブール値である必要があり、ifステートメントのタイプは「then」および「else」句のタイプと同じであると言えます。 1と2が数値であることがわかっているので、置換によって、「if」ステートメントが数値であることがわかります。

物事が厄介になるところ、そして私がしばらく理解できなかったことは、letを扱っています:

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

ここでは、渡したものをすべて返す関数に「id」をバインドしました。これは、恒等関数とも呼ばれます。問題は、関数のパラメーター 'x'のタイプがidの使用法ごとに異なることです。 2番目の「id」はa-> aの関数で、aは何でもかまいません。 1つ目は(a-> a)->(a-> a)からです。これはlet-polymorphismとして知られています。重要なのは、特定の順序で制約を解決することです。最初に、「id」の定義の制約を解決します。これはa-> aになります。次に、idのタイプの新しい個別のコピーを、使用される各場所の制約に置き換えることができます。たとえば、a2-> a2およびa3-> 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

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

27
Paul

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

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

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

6
Wei Chen

型とプログラミング言語by Benjamin C. Pierce

4

Lambda the Ultimate、開始 ここ

3
Doug Currie