Failed to match expected type `Int 'with actual type` Integer'

I have the following Haskell code:

-- Problem 69 import ProjectEuler phi :: Integer -> Integer phi n = n * product [p - 1 | p <- primeDivisors n] `div` product [p | p <- primeDivisors n] -- primeDivisors n is a list of the prime divisors of n maxRatio :: (Int, Int, Double) -> (Int, Int, Double) -> (Int, Int, Double) maxRatio t1@(_, _, x) t2@(_, _, y) | x > y = t1 | otherwise = t2 main = print (foldl maxRatio (0, 0, 0.0) [(n, phi n, ratio) | n <- [2..max], let ratio = fromIntegral n / (fromIntegral (phi n))] ) where max = 1000 

which gives the following error:

 Couldn't match expected type `Int' with actual type `Integer' In the expression: n In the expression: (n, phi n, ratio) In the third argument of `foldl', namely `[(n, phi n, ratio) | n <- [2 .. max], let ratio = fromIntegral n / (fromIntegral (phi n))]' 

I suspect that in the triple (0, 0, 0.0) 0 are of type Int . Is 0 always an Int type or does ghci infer a type like Int in this case? If later, how can I get it to be an Integer type instead? Or is there something else causing this error?

+8
haskell
source share
4 answers

Haskell can usually infer the type of numeric literals, such as 0 , like any suitable type that you need. This is because he knows with what functions you transfer them; if I have a function phi :: Integer -> Integer and I call phi 0 , Haskell knows that this 0 must be Integer . It is also fine if I call the function pho :: Int -> Int with pho 0 ; that particular 0 is defined as Int .

However, Int and Integer are different types, and no concrete 0 can be passed for both phi and pho .

Your problem is simply that the sets that maxRatio deals with are typed (by you) (Int, Int, Double) , but one such tuple is built like (n, phi n, ratio) . Since phi accepts and returns Integer , n in this expression must be Integer . But then this does not work for maxRatio , so you get an error.

Depending on what type you really wanted ( Int or Integer ), all you have to do is change the signature like phi or maxRatio so that they work with the same number, Haskell will decide that your literally written 0 is this is any digital type needed to do this job, provided it can make it work!

Note that the error message reported that it was n in (n, phi n, ratio) , which was supposed to be Int and was actually Integer . The tuple (0, 0, 0.0) never mentioned. Often type errors occur somewhere other than where the compiler tells you (since all the compiler can do is that different output chains cause conflicting requirements for the type of something, without being able to find out which part of the whole process is "wrong",), but in this case it was pretty good.

Haskell gains (rightly justified) a bad reputation for infallible error messages, but it can help a lot to start with what the compiler tells you and try to find out why the facts are complaining about your code. It will be painful at first, but you will quickly develop basic literacy in Haskell error messages (at least simpler ones) that will help you quickly detect these errors, which makes the compiler very powerful error detection for you.

+15
source share

n is inferred as Int because of the type maxRatio , while the type phi says it should be Integer . The simplest solution is to change the type maxRatio to use Integer or even just a , since it does not apply to these values.

+4
source share

This is output, so you can simply change the signature like maxRatio . However, if you need to change the explicit Int to Integer , use toInteger :: (Integral a) => a -> Integer

+3
source share

Signatures of your type are incompatible - replace Int with Integer .

+1
source share

All Articles