简体   繁体   English

无法将预期类型“Int”与实际类型“Integer”匹配

[英]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 . 但是IntInteger是不同的类型,并且不能将特定的0传递给phipho

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. 根据您实际想要的类型( IntInteger ),您需要做的就是更改phimaxRatio的类型签名,以便它们使用相同类型的数字。 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.

相关问题 Haskell无法将期望的类型“ Integer”与实际类型“ [Integer]”进行匹配 - Haskell Couldn't match expected type `Integer' with actual type `[Integer]' 无法将期望的类型[a]与实际类型“整数-&gt; [整数]”匹配 - Couldn't match expected type [a] with actual type `Integer -> [Integer]' 无法将预期类型“ [Integer]”与实际类型“ Integer”匹配 - Couldn't match expected type ‘[Integer]’ with actual type ‘Integer’ 无法将期望类型“Int”与实际类型“IO [Int]”匹配 - Couldn't match expected type `Int' with actual type `IO [Int]' 无法将预期类型“Int”与实际类型[Int]匹配 - Couldn't match expected type `Int' with actual type [Int] 无法将预期类型“[Int]”与实际类型“Int”相匹配 haskell - Couldn't match expected type ‘[Int]’ with actual type ‘Int’ haskell 如何将(Integer,Int,Int)转换为Day。 无法将预期的类型“天”与实际类型“((Integer,Int,Int)””匹配 - How to convert (Integer, Int, Int ) to Day. Couldn't match expected type ‘Day’ with actual type ‘(Integer, Int, Int)’ 无法将预期的类型&#39;Integer-&gt; t&#39;与实际类型匹配 - Couldn't match expected type 'Integer -> t' with actual type 无法将预期类型&#39;Integer - &gt; t&#39;与实际类型&#39;Bool&#39;匹配 - Couldn't match expected type ‘Integer -> t’ with actual type ‘Bool’ Haskell:无法预期实际类型&#39;Int&#39;的&#39;Integer&#39;类型 - Haskell: Couldn't expected type 'Integer' with actual type 'Int'
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM