昨日の日記の続きで、各関数の型を追記しようと思ってたんですが…
*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が選ばれるんでしょうね。何か合理的な理由でもあるんでしょうか。