【问题标题】:Haskell - Cannot understand this type mismatch errorHaskell - 无法理解这种类型不匹配错误
【发布时间】:2015-03-06 20:53:58
【问题描述】:

我有以下代码(yyyymm 定义为类型 Int):

partOne = truncate  ((fromIntegral yyyy + fromIntegral mm/100) * 1.25 + 0.97)

加载到 GHCi 时出现错误:

没有因使用“截断”而产生的 (Integral Float) 实例

但是,如果我直接在 GHCi 中使用以下行,它就可以正常工作:

truncate  ((fromIntegral 2000 + fromIntegral 04/100) * 1.25 + 0.97)

Int 类型似乎存在一些问题,但我不知道如何解决。

另外,实际上我并不完全理解(Integral Float) 在这里的含义。


为了完整起见,这里包含了整个函数的定义,以防错误是由整个事物而不是单个语句引起的:

dowNumber :: Mnemonic -> PhonePad -> Date -> Float
dowNumber mn p (yyyy, mm, dd) = (partOne + partTwo) / 7 where
  partOne = (truncate  ((fromIntegral yyyy + (fromIntegral mm)/100) * 1.25 + 0.97))
  partTwo = fromIntegral ((monthToPhone mn p mm) + dd)

Mnemonic 只是 StringPhonePad[(Char, Int)]Date(Int, Int, Int)

【问题讨论】:

  • 注意:StackOverflow 的 markdown 变体不知道有围栏的代码块,你需要使用缩进。

标签: haskell types


【解决方案1】:

嗯,truncate(RealFrac a, Integral b) => a -> b 类型,这意味着它的多态结果需要满足Integral 约束。但是,dowNumber 的类型表明(partOne + partTwo) / 7Float。因此,partOnepartTwo 需要是Floats。

如果Float 是某种整数类型,那将是可能的。但事实并非如此。但是要从Integral 获得浮动,所缺少的只是另一个fromIntegral,或者partOne

partOne = fromIntegral $ truncate $ …

或者在你尝试划分之前:

dowNumber … = fromIntegral (partOne + partTwo) / 7 where 
   …

如何更轻松地修复此类错误?

注释类型。在这种特定情况下,GHC 抱怨truncate,因此抱怨partOne。让我们简化一下您的示例:

number :: Float
number = (a + b) / 2 where
  a = truncate $ fromIntegral 5 / 2 
  b = fromIntegral $ 12

这会产生与您之前的程序相同的错误:

SO.hs:3:7: 没有因使用“截断”而产生的 (Integral Float) 实例 在表达式中:截断 在表达式中: truncate $ fromIntegral 5 / 2 在“a”的等式中:a = truncate $ fromIntegral 5 / 2

那么,a 的等式不正确?让我们修复ab 的类型:

number :: Float
number = (a + b) / 2 where
  a, b :: Int
  a = truncate $ fromIntegral 5 / 2 
  b = fromIntegral $ 12

现在很清楚了:

SO.hs:2:11: 无法将预期类型“Float”与实际类型“Int”匹配 在‘(+)’的第一个参数中,即‘a’ 在‘(/)’的第一个参数中,即‘(a + b)’ SO.hs:2:15: 无法将预期类型“Float”与实际类型“Int”匹配 在‘(+)’的第二个参数中,即‘b’ 在‘(/)’的第一个参数中,即‘(a + b)’ 失败,加载模块:无。

【讨论】:

  • 解决了这个问题。谢谢。所以(Integral Float) 这个东西实际上是指(Part1 / Part2)?那么错误消息实际上是不是有点误导。似乎是在说是truncate 的论点导致了这个问题,而实际上是它的结果。
猜你喜欢
  • 1970-01-01
  • 2016-02-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-09-15
相关资源
最近更新 更多