Haskell - 无法理解此类型不匹配错误

Haskell - Cannot understand this type mismatch error

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

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

加载到 GHCi 时出现错误:

没有因使用“截断”而产生的(整数浮点数)实例

然而,如果我直接在 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).

嗯,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:
    No instance for (Integral Float) arising from a use of ‘truncate’
    In the expression: truncate
    In the expression: truncate $ fromIntegral 5 / 2
    In an equation for ‘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:
    Couldn't match expected type ‘Float’ with actual type ‘Int’
    In the first argument of ‘(+)’, namely ‘a’
    In the first argument of ‘(/)’, namely ‘(a + b)’

SO.hs:2:15:
    Couldn't match expected type ‘Float’ with actual type ‘Int’
    In the second argument of ‘(+)’, namely ‘b’
    In the first argument of ‘(/)’, namely ‘(a + b)’
Failed, modules loaded: none.