明示的なアプリケーションまたはサブタイプなしの上位の多態性?


7

したがって、言語でより高いランクのポリモーフィズムを持つ2つの主な戦略に精通しています。

  • System-Fスタイルのポリモーフィズム。関数は明示的に型指定され、インスタンス化は型アプリケーションを通じて明示的に行われます。これらのシステムは命令的である場合があります。
  • サブタイピングベースのポリモーフィズム。ポリモーフィックタイプは、そのすべてのインスタンス化のサブタイプです。決定可能なサブタイピングを行うには、ポリモーフィズムが予測的でなければなりません。このペーパーでは、そのようなシステムの例を示します。

ただし、Haskellのような一部の言語では、明示的な型アプリケーションを使用せずに、命令的に高いランクの多態性を持っています。

これはどのようにして可能ですか?明示的なインスタンス化またはキャストなしで、サブタイプの概念なしで型をインスタンス化する場合、型チェックは「知る」ことができますか?

または、そのようなシステムではタイプチェックは決定可能ですか?これは、Haskellのような言語が、ほとんどの人のユースケースでうまく機能する決定不能なものを実装するケースですか?

編集:

明確にするために、私は多態的に型付けされた値の定義ではなく使用に興味があります。

たとえば、次のように仮定します。

f : forall a . a -> a
g : (forall a . a -> a) -> Int
val = (g f, f True, f 'a')

f引数として与えられたときではなく、それが適用されたときにインスタンス化する必要があることをどのようにして知ることができますか?

または、関数型から自分自身を分離するには:

f : forall a . a
g : (forall a . a) -> Int
val = (g f, f && True, f + 0)

ここでは、を使用fするかどうかを渡すことと渡すことを区別することもできません。引数として&&and に渡されるとインスタンス化されますが、にはインスタンス化され+ませんg

理論的なシステムでは、魔法のような「あらゆる多相型をインスタンスに変換できます」というルールなしに、これら2つのケースをどのように区別できますか?またはそのようなルールで、決定性を保つために、いつそれを適用するかを知ることができますか?


Haskellは、ユーザーが明示的に指定しない限り、型変数のポリタイプを推測しません。たとえば\f -> (f True, f 'a')、型を割り当てることができる場合でも、型チェックは行われません(forall t. t->t) -> (Bool, Char)
chi

@chi ポリモーフィック値の定義ではなく用途に興味があります。私の意味の例については、私の編集を参照してください。これが最初は明確でなかった場合は申し訳ありません。
jmite 2017年

推論アルゴリズムを説明するSimon Peyton-Jonesの論文がいくつかあるはずです(ただし、どれを指摘することはできません)。しかし、おそらく推論エンジンgは、それがポリタイプを予期していることを認識でき、のインスタンス化を妨げますf
2017年

回答:


7

Dunfield&Krishnaswamiの論文の紹介では、任意ランク型の実用的な型推論を参照しています

見て分かるように、それは高度な型システムにうまくスケーリングします。さらに、実装は簡単で、比較的高品質のエラーメッセージが生成されます(Peyton Jones et al。2007)

System F風のアプローチでは、「サブタイプ」関係もあります。See section 3.3包摂。


また、Haskellには命令型(またはそれらの推論)がないことも強調しておきます。ポインタについては、https//mail.haskell.org/pipermail/ghc-devs/2016-September/012940.htmlを参照してください。

  • 可視の型引数にポリタイプを書き込むことができます。例えば。f @(forall a。a-> a)
  • 署名の型の引数としてポリタイプを書き込むことができます。例:f :: [forall a。a-> a]-> Int

    そして、それだけです。統一変数STILLはポリタイプと統合できません。ポリタイプでポリモーフィック関数を呼び出す唯一の方法は、Visible Type Applicationを使用することです。

つまり、ポリタイプで関数を呼び出す場合は、VTAを使用する必要があります。シンプル、簡単、予測可能。そして間違いなく迷惑です。しかし、可能です。

すなわち、id id常に精巧になります

forall a. id @(a -> a) (id @a)

ない

id @(forall a. a -> a) id

ただし、を有効にすると、後者を明示的に記述できますImpredicativeTypes


3

以下のような関数の適用を確認するにはg : (forall a. a -> a) -> Intf、私たちはそれをチェックする必要がありますf : forall a. a -> a

量化子を一致させる(かなりもろい)代わりに、フレッシュでリジッドな(つまり、ユニファイできない)変数を導入します。たとえばa1、それを確認する必要がありf : a1 -> a1ます。これfで、通常どおり続行してa1(modulo追加がa1その範囲をエスケープしないことを確認するためのチェック)。

実際のアルゴリズムの詳細は、リンクされたphadejの論文に記載されています。

または、そのようなシステムではタイプチェックは決定可能ですか?これは、Haskellのような言語が、ほとんどの人のユースケースでうまく機能する決定不能なものを実装するケースですか?

より高いランクの多型が存在する場合の型推論の一般的な問題は、決定できません。ただし、完全な型注釈を使用すると、(ほぼ?)決定可能な型チェックの問題になります。したがって、GHCのアルゴリズムは不完全である必要がありますが、これらの2つの状況の真ん中にできる限り多くの根拠をカバーするために、いくつかのスパースタイプアノテーションを使用します。

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