bonotakeの日記

元・ソフトウェア工学系研究者、今・AI系エンジニア

monomorphism restriction

昨日の日記の続きで、各関数の型を追記しようと思ってたんですが…

*Main> :t g
g :: (Num b) => (b, b, b) -> b
*Main> :t g1_1
g1_1 :: (Num b) => (b, b) -> b -> b
*Main> :t g1_2
g1_2 :: (Integer, Integer) -> Integer -> Integer
*Main> :t g2
g2 :: Integer -> Integer -> Integer -> Integer

g1_2とg2が怪しいことになってしまいました。
さかいさんに聞くと、monomorphism restriction (単相性制限)とかいうやつだそうで。

GHCだと、-fno-monomorphism-restriction というフラグをセットするとこの制約は外れます。
[追記]GHC 6.10.1 からは非推奨になってるそうです。詳しくはコメントを。[/追記]

*Main> :t g2
g2 :: Integer -> Integer -> Integer -> Integer
*Main> :set -fno-monomorphism-restriction
*Main> Compiling Main             ( C:/home/imai/lab/haskell/hoge.hs, interpreted )
Ok, modules loaded: Main.
*Main> :t g2
g2 :: (Num c) => c -> c -> c -> c

あるいは、ちゃんと引数を与えて定義するとか。

*Main> let g2_1 = curry $ curry3 g
*Main> :t g2_1
g2_1 :: Integer -> Integer -> Integer -> Integer
*Main> let g2_2 x = (curry $ curry3 g) x
*Main> :t g2_2
g2_2 :: (Num c) => c -> c -> c -> c

しかし、数あるNumクラスのインスタンスの中で、どうしてIntegerが選ばれるんでしょうね。何か合理的な理由でもあるんでしょうか。

注:bonotakeは、amazon.co.jpを宣伝しリンクすることによってサイトが紹介料を獲得できる手段を提供することを目的に設定されたアフィリエイト宣伝プログラムである、 Amazonアソシエイト・プログラムの参加者です。