web-dev-qa-db-ja.com

Hindley-Milner推論はGo言語で機能しますか?

私は Hindley-Milner がサブクラスを持つ型システムでは機能しないことを読みました。また、他の型システムの機能でも機能しません。 Goは現在、:=演算子の型推論を非常に制限しています。しかし、Goには従来の意味でのサブクラスはありません。Hindley-Milner推論で正常に機能するHaskellの型クラスに非常によく似たインターフェースのみがあります。

では、Hindley-Milnerの推論は、Haskellの場合と同じように、Goでも原理的に機能するのでしょうか。または、Goにはそれを壊す他の機能がありますか? (その一方で、HaskellにはHindly-Milnerで機能しないいくつかの機能もあります。これらの機能を使用する場合、プログラムのこれらの部分を手動で入力する必要があります。)

22
JanKanis

Hindley-Milner型推論は、System-F型システムの制限であるHindley-Milner型システムに使用されます。 HM型システムの興味深い特徴は、それらがparametric polymorphism(aka。generics)を持っていることです。これは、Golangが拒否している最大の型システム機能です。

その苛立たしい制限により、HMスタイルの型推論は不可能です。型付けされていないコードを見てみましょう:

_func f(a) {
  return a.method()
}
_

fのタイプは何ですか? aにはメソッドが必要なので、匿名のインターフェースfunc f(a interface { method() ??? }) ???を使用できます。ただし、戻り値の型が何であるかはわかりません。型変数を使用すると、型を次のように宣言できます

_func f[T](a interface{ method() T }) T
_

ただし、Goには型変数がないため、これは機能しません。暗黙的なインターフェースは型推論のいくつかの側面を容易にしますが、現在、関数呼び出しの戻り型を見つける方法はありません。 HMシステムでは、すべての関数を暗黙的に宣言するのではなく宣言する必要があり、それぞれの名前は単一の型のみを持つことができます(Goのメソッドは異なるインターフェースで異なる型を持つことができます)。

代わりに、Goでは関数を常に完全に宣言する必要がありますが、変数で型の推論を使用できます。これは、割り当ての右側に_variable := expression_がプログラムのその時点で既知の型を持っているために可能です。この種の型推論は、単純で正確で線形です。

  • 変数の型は宣言の時点ですぐにわかりますが、HMの推論では、プログラム全体を最初に型チェックする必要があります。これは、エラーメッセージの品質にも大きな影響を与えます。
  • Goの型推論アプローチは、最も一般的な型を選択するHMとは対照的に、変数に対して最も具体的な型を常に選択します。これは、Goの暗黙のインターフェイスを使用しても、サブタイピングで問題なく機能します。
35
amon