[英]Couldn't match expected type `Int' with actual type `Integer'
I have the following Haskell code: 我有以下Haskell代码:
-- 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)
the 0's are type Int
. 我怀疑在三元组(0, 0, 0.0)
,0是Int
类型。 Is 0
always type Int
or is ghci deducing the type as Int
in this case? 在这种情况下, 0
总是输入Int
还是ghci将类型推断为Int
? If the later, how do I force it to be type Integer
instead? 如果是后者,我该如何强制它输入Integer
? Or is there something else that causes this error? 或者是否有其他原因会导致此错误?
Haskell can generally infer the type of numeric literals such as 0
as whatever appropriate type you need them to be. Haskell通常可以推断出数字文字的类型,例如0
就像你需要它们一样合适的类型。 This is because it knows what functions you pass them to; 这是因为它知道你传递给他们的功能; if I have a function phi :: Integer -> Integer
, and I call phi 0
, Haskell knows that that particular 0
must have been an Integer
. 如果我有一个函数phi :: Integer -> Integer
,我调用phi 0
,Haskell知道那个特定的0
必须是一个Integer
。 It's also fine if I call a function pho :: Int -> Int
with pho 0
; 如果我用pho 0
调用函数pho :: Int -> Int
也没关系; that particular 0
is inferred to be an Int
. 该特定0
被推断为一个Int
。
However Int
and Integer
are different types, and there's no way one particular 0
can be passed to both phi
and pho
. 但是Int
和Integer
是不同的类型,并且不能将特定的0
传递给phi
和pho
。
Your issue is simply that the tuples that maxRatio
deals with are typed (by you) (Int, Int, Double)
, but that one such tuple is constructed as (n, phi n, ratio)
. 你的问题只是maxRatio
处理的元组是由你输入的( (Int, Int, Double)
,但是这样的元组被构造为(n, phi n, ratio)
。 Since phi
takes and returns Integer
, the n
in that expression has to be an Integer
. 由于phi
接受并返回Integer
,因此该表达式中的n
必须是Integer
。 But then that doesn't work for maxRatio
, so you get the error. 但是那对maxRatio
,所以你得到了错误。
Depending on which type you actually wanted ( Int
or Integer
), all you need to do is change the type signature of phi
or maxRatio
so that they're working with the same kind of number. 根据您实际想要的类型( Int
或Integer
),您需要做的就是更改phi
或maxRatio
的类型签名,以便它们使用相同类型的数字。 Haskell will decide that your literally written 0
s are whatever numeric type is necessary to make that work, provided there is one that can make it work! Haskell将决定你的字面上写的0
是什么数字类型是必要的,以使其工作, 只要有一个可以使它工作!
Note that the error messaged specifically told you that it was n
in (n, phi n, ratio)
that was expected to be an Int
and was actually an Integer
. 需要注意的是传递消息的错误明确告诉你,这是n
在(n, phi n, ratio)
这是预计的Int
和实际上是一个Integer
。 The (0, 0, 0.0)
tuple is never mentioned. 永远不会提到(0, 0, 0.0)
元组。 Often type errors originate somewhere other than where the compiler points you (since all the compiler can do is spot that different chains of inference produce inconsistent requirements on the type of something, with no way to know which part of the whole process is "wrong"), but in this case it did pretty well. 通常,类型错误源于编译器指向您的位置以外的其他位置(因为编译器可以做的就是发现不同的推理链对某些类型的类型产生不一致的要求,无法知道整个过程的哪个部分是“错误的” ),但在这种情况下,它做得很好。
Haskell gets a (fairly justified) bad rep for inscrutable error messages, but it can help a lot to start from what the compiler is telling you is the problem and try to figure out why the facts it's complaining about arise from your code. Haskell得到了一个(相当合理的)糟糕的代表,因为它不可思议的错误消息,但它可以帮助很多东西从编译器告诉你的问题开始,并试图弄清楚为什么它的抱怨来自你的代码。 This will be painful at first, but you'll quickly develop a basic literacy in Haskell's error messages (at least the more straightforward ones) that will help you spot these kinds of errors really quickly, which makes the compiler a very powerful error-detection system for you. 这一开始会很痛苦,但是你会很快在Haskell的错误消息(至少是更直接的错误消息)中开发一个基本知识,这将有助于你真正快速地发现这些类型的错误,这使编译器成为一个非常强大的错误检测系统为你服务。
n
is being inferred as Int
due to the type of maxRatio
, while the type of phi
says it should be Integer
. 由于maxRatio
的类型, n
被推断为Int
,而phi
的类型则表示它应该是Integer
。 The simplest fix is to change the type of maxRatio
to use Integer
or even just a
since it doesn't touch those values. 最简单的解决方法是将maxRatio
的类型maxRatio
为使用Integer
,甚至只更改a
因为它不会触及这些值。
It's being inferred, so you can just change the type signature of maxRatio
. 它是推断的,所以你可以改变maxRatio
的类型签名。 Still, if you ever need to change an explicit Int
to an Integer
, use toInteger :: (Integral a) => a -> Integer
但是,如果您需要将显式Int
更改为Integer
,请使用toInteger :: (Integral a) => a -> Integer
您的类型签名不一致 - 始终将Int
替换为Integer
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.