したがって、言語でより高いランクのポリモーフィズムを持つ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つのケースをどのように区別できますか?またはそのようなルールで、決定性を保つために、いつそれを適用するかを知ることができますか?
g
は、それがポリタイプを予期していることを認識でき、のインスタンス化を妨げますf
。
\f -> (f True, f 'a')
、型を割り当てることができる場合でも、型チェックは行われません(forall t. t->t) -> (Bool, Char)