MarkJonesとOlegKiselyovのチュートリアルに従って、Hindley-Milner型推論アルゴリズムを実装しています。これらは両方とも、おおよその形式のタイプで「バインディングの適用」操作を行います
applyBindings :: TyEnv -> Type -> Type
これは、指定されたにtyvar -> ty
バインディングを適用します。を呼び出すのを忘れることは私のコードでよくある間違いであることがわかりました。また、と同じ型を持っているため、Haskellの型システムから助けを得ることができません。型システムで次の不変条件を適用する方法を探しています。TyEnv
Type
applyBindings
ty
applyBindings tyenv ty
型推論を行う場合、「最終的な」結果を返す前にバインディングを適用する必要があります
単形オブジェクト言語の型推論を行う場合、wren ng thorntonのunification-fdパッケージに実装されているように、これを強制する自然な方法があります。sの2つのデータ型を定義しますType
。
-- | Types not containing unification variables
type Type = ... -- (Fix TypeF) in wren's package
-- | Types possibly containing unification variables
type MutType = ... -- (MutTerm IntVar TypeF) in wren's package
applyBindings
タイプを与える
-- | Apply all bindings, returning Nothing if there are still free variables
-- otherwise just
applyBindings :: TyEnv -> MutType -> Maybe Type
(この関数は実際freeze . applyBindings
にはunification-fdにあります)。これにより、不変条件が適用されます。忘れるとapplyBindings
、型エラーが発生します。
これは私が探している種類の解決策ですが、ポリモーフィズムを持つオブジェクト言語の場合です。上記のアプローチは、現状では適用されません。オブジェクト言語の型には型変数がある可能性があるためです。実際、バインディングを適用した後に変数が解放された場合、戻りたくないのですNothing
が、一般化したいと思います。これらの変数。
私が説明する線に沿った解決策、つまりとはapplyBindings
異なるタイプを与える解決策はありconst id
ますか?実際のコンパイラーは、MarkとOlegのチュートリアルが使用するのと同じしゃれ(統合変数とオブジェクト言語型変数の間)を使用しますか?