もしRubyistがHaskellを学んだら(16) 型推論と型注釈
タグ: learning_haskell / 初版公開: 2014-01-10

Haskellは型推論を備えた言語であり、静的型付けでありながら型を明記しなくても、型を推測してコンパイルすることができる。この点は動的型付けでダックタイピングなRubyとは対極である。

しかし、静的型付けという性質上、型が推測できない場合は明示的に型を指定してやる必要があり、それをするのが型注釈という機能である。今回はHaskellの型推論と型注釈の使い方について整理してみる。

Read型は文字列を受け取りReadのインスタンスの型の値を返すインタフェースを実装している。それがread関数である。GHCiでread関数の型を確認してみると、以下のとおりになっている。

Prelude> :t read
read :: Read a => String -> a

GHCiで試しにreadを使って以下のコードを実行させてみると、確かに型が推論されて文字列が数値に解釈され、計算結果が表示される。

Prelude> read "5" + 3
8

これが実行できるのはreadの結果をInt型の3と加算することから、Haskellが気を利かせてreadの返り値がInt型だと型推論を行ったためである。

では意地悪をして、read関数を単独で実行してみるとどうだろうか。想像通りこれはエラーとなる。readRead a => String -> aなので、型変数aの型が不明だとコンパイルできないのだ。

Prelude> read "5"

<interactive>:3:1:
    Ambiguous type variable `a0' in the constraint:
      (Read a0) arising from a use of `read'
    Probable fix: add a type signature that fixes these type variable(s)
    In the expression: read "5"
    In an equation for `it': it = read "5"

このような場合に、Haskellに型を教えてやる方法が型注釈だ。型注釈は::に続けて型を書いてやることで、式の型を明示的にHaskellに伝える。先ほどのread "5"に型注釈をつけて実行させてみよう。

Prelude> read "5" :: Int
5

これで狙い通り文字列"5"Int型の数値5に変換することができた。Rubyであれば"5".to_iなどとする文字列と数値の変換が、Haskellでは型クラスと型推論、型注釈という別のパラダイムによって実現できたわけだ。

Haskellの型クラスと型推論については”すごいHaskellたのしく学ぼう!”の2章で解説されている。この本は本当に読みやすく、おすすめ。

すごいHaskellたのしく学ぼう!
Miran Lipovača
オーム社
売り上げランキング: 126,678