I am new to Haskell from a C++ and Java background. Occassionally, I have trouble with Haskell’s type system. My current error is with this piece of code:
countIf :: (Integral b) => [a] -> (a -> Bool) -> b
countIf [] p = 0
countIf (x:xs) p
| p x = 1 + countIf xs p
| otherwise = countIf xs p
isRelativelyPrime :: (Integral a) => a -> a -> Bool
isRelativelyPrime m n = gcd m n == 1
phi :: (Integral a, Integral b) => a -> b
phi n = countIf [1..(n - 1)] (isRelativelyPrime n)
main = print [(n, phi n, ratio) | n <- [1..10], let ratio = (fromIntegral (phi n)) / n]
The error message is
prog.hs:13:60:
Ambiguous type variable `b' in the constraints:
`Fractional b' arising from a use of `/' at prog.hs:13:60-85
`Integral b' arising from a use of `phi' at prog.hs:13:75-79
Probable fix: add a type signature that fixes these type variable(s)
13:60 is just before the usage of fromIntegral in the let binding in my list comprehension in main. I’m still trying to get used to ghc’s error messages. I am unable to decipher this particular one in order to figure out what I need to change to get my code to compile. Any help will be greatly appreciated. Thanks.
You need to call fromIntegral on n as well since Haskell doesn’t automatically convert from integral types, which you already seem to know since you called fromIntegral (phi n). I make this mistake all the time, not a big deal!