余白の書きなぐり

aueweのブログ

Haskellの型推論でハマった話

久しぶりにHaskellで遊んでたらハマったのでメモ。 100の階乗 100!=1*2*...*100 の桁数を求めるプログラムを書いた。

main = print $ kaijo 100
kaijo n = length $ show $ product [1..n]
-- 158が表示される。

上記のプログラムは正しい値(158)を返すが、下記のように型を明示すると、誤った値(0)を返す。

main = print $ kaijo 100
kaijo :: Int -> Int
kaijo n = length $ show $ product [1..n]
-- 0が表示される。なんでや!!

ちなみに100ではなく10の階乗なら、どちらのプログラムも正しい結果を返す。 この不条理の原因は、Intを明示するとproduct関数の計算がIntで実行されて、 100の階乗という大きな値が桁溢れを起こすせいだと思われる。 Intを明示しなければ、自動で多倍長計算してくれる。

「100を158にする関数」なのに、Int -> Intとするとバグっちゃう。こわいこわい。