型推論

出典: フリー百科事典『ウィキペディア(Wikipedia)』
移動先: 案内検索

型推論(かたすいろん)とはプログラミング言語の機能の1つで、静的な型付けを持つ言語において、変数関数を宣言しなくてもそれを導くのに使われた関数の型シグネチャなどから自動的に型を決定する機構のこと。

推論に失敗するとその時点でエラーを報告できるため、少なくとも誤った型を用いる事によるバグは回避できる。また、記述をアルゴリズムに集中できるのでプログラムの抽象度が上がるというメリットもある。

代表的な型推論アルゴリズムとして、Hindley/Milner 型推論アルゴリズムがある。各々著名なコンピュータ科学者の名前からつけられた名前であるが、Hindley は論理学者として型推論システムを先に開発した。

型推論を持つ言語としてはHaskellMLValaF#C#JavaScalaOCamlD言語Concurrent CleanC++11Swiftなどがある。静的型付け関数型言語のほとんどがなんらかの型推論の機能を持っている。

非技術的な説明[編集]

ほとんどの言語においては、関数仮引数および戻り値ローカル変数等は、それらがもつデータの種類を表すをもつ。実行時にならないと型がわからない言語を動的型付けの言語という。一方、コンパイル時に型がわかる言語を静的型付けの言語という。静的型付けの言語において、関数の仮引数および戻り値の型やローカル変数の型は、通常は明示的に表記する必要がある。例えば、次はC言語の例である。

int addone(int x) {
    int result;

    result = x+1;
    return result;
}

関数定義の最初の行int addone(int x)では、addoneは整数一つを入力としてとり、整数を結果として出力する、と宣言している。int result;の行では、ローカル変数resultが整数型であることを宣言している。

型推論の機能がある言語では、例えば次のように書くことができるだろう。

addone(x) {
    var result;

    result = x+1;
    return result;
}

この書き方は動的型付けの言語に非常によく似ているが、しかしながらすべての型はコンパイル時に定められる。この仮想的な例では、+演算子は常に二つの整数を一つの整数に変換する。これから、x+1の値が整数であることが型推論によって推論される。故にresultの型は整数であり、addoneの返り値が整数であることがわかる。同様に+演算子が入力として整数をとることからxが整数であることがわかり、addoneの引数の型が整数であることがわかる。

型推論のバリエーション[編集]

上記例では変数宣言の際の暗黙的な型指定を挙げているが、varだけが型推論ではない。
下記のように、自動的に型を決定する機構はvar以外にも存在しうる。変数宣言の際の暗黙的な型指定のみを指して「型推論」と表現することは混乱を招くので注意されたい。

総称型の型推論の例[編集]

例えば、Javaではバージョン5.0の頃からメソッドスコープの型変数を推論する機能を持つ。

 // 推論を用いない書き方
 List<String> list1 = Collections.<String>emptyList();
 // 型変数へのバインドに型推論を用いた書き方
 List<String> list2 = Collections.emptyList();

その他、Java 7 からは型変数を持つクラスをnewする場合にバインドすべき型を推論するダイヤモンド・オペレーターという機能を持つ。

 // 推論を用いない書き方
 List<String> list1 = new ArrayList<String>();
 // ダイヤモンドオペレーターによる推論
 List<String> list2 = new ArrayList<>();

無名関数の型推論の例[編集]

無名関数の型推論においては、複雑な状況が発生する。

C#の例を以下に示す。

// 複数のデリゲート型を定義
delegate void TwoStringAction(string left, string right);
delegate void OneParamAction(object o);
delegate void TwoParamAction(object o, EventArgs e);
delegate void TwoIntegerAction(int x, int y);

// メソッドのオーバーロードを用意する。有効化するオーバーロードの種類により、型推論の可否が変化する。
static void SomeMethod(TwoStringAction action) { /* Pattern 1 */ }
//static void SomeMethod(OneParamAction action) { /* Pattern 2 */ }
//static void SomeMethod(TwoParamAction action) { /* Pattern 3 */ }
//static void SomeMethod(TwoIntegerAction action) { /* Pattern 4 */ }

static void Main() {
    // メソッドのオーバーロードがPattern 1のみの場合、全ての文が有効(型推論可能)である。
    SomeMethod((o, e) => { /*No-op*/}); /* 1行目 */
    SomeMethod((o, e) => { o = o + e; }); /* 2行目 */
    SomeMethod((o, e) => { o = "" + o + e; }); /* 3行目 */
    SomeMethod(delegate { /*No-op*/ }); /* 4行目 */
}
  • SomeMethod(OneParamAction action) の行を有効にすると、Mainメソッドの4行目の型推論が効かなくなる。
    • 4行目の匿名関数は引数リストを省略できるため、1引数、2引数のどちらのデリゲート型か曖昧になる。
  • SomeMethod(TwoParamAction action) の行を有効にすると、Mainメソッドの2行目以外の型推論が効かなくなる。
    • 1行目のラムダは、2引数で値を返さない複数のデリゲート型がある場合、曖昧となる。
    • 3行目のラムダは、代入式の左辺にあるostringを格納できる型でなければならないが、
      一方で右辺のoeは暗黙にToString()が呼び出されるため、いずれの型であってもよく、TwoStringAction TwoParamActionの間で曖昧となる。
    • 2行目のラムダは、oeの間に適切なoperator+が定義されなければならず、TwoStringAction型と推論される。
  • SomeMethod(TwoIntegerAction action) の行を有効にすると、Mainメソッドの3行目以外の型推論が効かなくなる。
    • 2行目のラムダは、oestringintのいずれでもoperator+が実行できるため、TwoStringActionTwoIntegerActionの間で曖昧となる。
    • 3行目のラムダは、代入式の左辺にあるostringを格納できる型でなければならないため、TwoStringAction型と推論される。

デリゲート型を引数に取るメソッドを複数用意する場合、オーバーロードではなく別名のメソッドとすることで、この複雑性は回避できる。

動的型言語における型推論[編集]

動的に型付けを行う言語の場合、文法的には型付けが行われず、あらゆる型の可能性を考慮して処理を進める必要があるため、処理が遅くなる原因となる[1]JITコンパイラによって高速化を図る場合、型推論によりあるデータを「特定の型」として扱うことが可能であれば、その型に合わせた処理だけをすることで高速化が行える[1]

JavaScript では、Webブラウザの分野では高速化が特に求められている[2]が、2011年12月20日にリリースされたFirefox 9から高速化のため型推論技術を採用している[3]

Groovy 2.0 ではコンパイル時型検査 @TypeChecked の機能をつけたが、型を指定していない変数に対しても、型推論を利用して変数に型を割り振り、型検査を行っている。同様に Groovy に対応した IntelliJ IDEA などの統合開発環境も型推論を利用してアシストを行っている。

脚注[編集]

[ヘルプ]
  1. ^ a b Type Inference brings JS improvements to Firefox Beta Brian Hackett, 2011年11月10日(2011年12月24日閲覧)。
    型推論により Firefox Beta の JavaScript が高速化しました(上の記事の和訳)、2011年12月24日閲覧。
  2. ^ 一色政彦 (2011年4月22日). “Internet Explorer 9正式版レビュー”. @IT. 2011年12月24日閲覧。
  3. ^ Mozilla、「Firefox 9」の正式版をリリース 「型推論」技術で45%高速に”. ITmedia (2011年12月21日). 2011年12月24日閲覧。