型推論の不思議

標準入力の各行にある数の合計を求めるプログラムを書いた。

main = do
        cs <- getContents
        print . sum . map read $ lines cs

以前はread関数を知らなかったので、ord関数とリスト操作を頑張ってやっていた。
readってすばらしい。けど、実数は読めないみたいだ。パースに失敗するエラーがでる。

コメントのとおり read に型指定すればいいだけなんだけど、そもそも、これコンパイルできてしまうことがなんだか不思議だ。read の戻り値は型推論では Num クラスであることしかわからないはずだけど、Num のデフォルトは Integer になるのかな。
ちなみに、警告オプションをつけてコンパイルするとちゃんと警告してくれる。

% ghc -Wall sum.hs -o sum

sum.hs:1:0: Warning: Definition but no type signature for `main'

sum.hs:2:24:
    Warning: Defaulting the following constraint(s) to type `Integer'
             `Read a' arising from use of `read' at sum.hs:2:24-27
             `Num a' arising from use of `sum' at sum.hs:2:16-18
             In the first argument of `map', namely `read'
             In the second argument of `(.)', namely `map read'
             In the second argument of `(.)', namely `sum . (map read)'

Haskell に限らず、警告オプションは常に有効にしておくべき。