[編集:それぞれにいくつかの単語を書いてください]
HM型推論を拡張する方法はいくつかあります。私の答えは、それらのいくつかを実装するための多くの、多かれ少なかれ成功した試みに基づいています。私が最初につまずいたのは、パラメトリック多型です。HMをこの方向に拡張しようとする型システムは、System Fに向かう傾向があるため、型注釈が必要です。私が出会ったこの方向の2つの注目すべき拡張機能は次のとおりです。
HMFは、すべてのSystem-F型の型推論を可能にします。つまり、型の「中間」で普遍的な数量化を行うことができ、その外観はHM多型のように暗黙的に最高のスコープに位置しません。この論文は、タイプ注釈がいくつ必要で、どこに必要かについて明確なルールが存在しないことを明確に述べています。また、タイプはSystem Fのタイプであり、通常、用語にはプリンシパルタイプはありません。
MLFはHMの拡張であるだけでなく、システムFの拡張でもあり、タイプに対する有界な数量化の一種を導入することでHMの主要なタイププロパティを取り戻します。著者によって比較が行われました。MLFはHMFよりも厳密に強力であり、注釈は多態的に使用されるパラメーターにのみ必要です。
HMを拡張する別の方法は、制約ドメインを変更することです。
HM(X)は、制約ドメインXでパラメーター化されたHindley-Milnerです。このアプローチでは、HMアルゴリズムはXのドメインソルバーに送信される制約を生成します。通常のHMの場合、ドメインソルバーは統合手順であり、ドメインはタイプおよびタイプ変数から構築される一連の用語。
Xの別の例は、Presburger算術の言語(この場合、型の推論/チェックが決定可能)またはPeano算術の言語(決定不可能)で表現される制約です。Xはさまざまな理論に沿って変化し、それぞれが必要なタイプアノテーションの量とローカリゼーションに関する独自の要件を持ち、まったくないものからすべてに至るまでさまざまです。
Haskellの型クラスは、フォームの型述語を追加することによる制約ドメインの一種の拡張ですMyClass(MyType)
(つまり、MyType型のMyClassのインスタンスが存在することを意味します)。
型クラスは基本的にアドホックポリモーフィズムを実装する(ほぼ)直交する概念であるため、型クラスは型推論を保持します。
例として、インスタンスなどを持つことができるval
タイプのシンボルを使用します。コード内でそのシンボルを参照するval :: MyClass a => a
場合MyClass A
、MyClass B
実際には型推論が既に実行されているため、コンパイラは使用するクラスのインスタンスを推測できます。これは、のタイプval
が使用されるコンテキストに依存することを意味します。また、単一のval
ステートメントを実行すると、ambiguous type error
:コンパイラは、コンテキストに基づいて型を推測できません。
GADT、タイプファミリ、依存型、システム(F)ωなどのより高度なタイプシステムの場合、タイプはもはや「タイプ」ではなく、複雑な計算オブジェクトになります。たとえば、同じように見えない2つのタイプが必ずしも異なるわけではないことを意味します。したがって、型の平等は自明ではありません(まったく)。
実際の複雑さの例を示すために、リストの依存タイプを考えてみましょう。NList a n
ここa
で、リスト内のオブジェクトのタイプn
とその長さです。
append関数にはtypeがappend :: NList a n -> NList a m -> NList a (n + m)
あり、zip関数にはがありますzip :: NList a n -> NList b n -> NList (a, b) n
。
ラムダがあると想像してください\a: NList t n, b: NList t m -> zip (append a b) (append b a)
。ここで、zipの最初の引数はtype NList t (n + m)
で、2番目の引数はtype NList t (m + n)
です。
ほとんど同じですが、型チェッカーが「+」が自然数で交換することを認識していない限り、(n + m)は文字通り(m + n)ではないため、関数を拒否する必要があります。型推論/型チェックについてではなく、定理証明についてです。
液体型は、いくつかの依存型推論を行っているようです。しかし、私が理解しているように、それは実際には依存型ではなく、静的境界を計算するために追加の推論が行われる通常のHM型のようなものです。
これがお役に立てば幸いです。