如何理解这种类型类错误,告诉我我使用了错误的类型?

时间:2019-06-08 11:00:12

标签: haskell types typeclass

这是我计算数字列表平均值的功能

arithMean :: (Fractional a) => [a] -> a
arithMean list = (foldr (+) 0 list)/ (length list)

但是,它在下面引发了一个错误

HigherOrder.hs:10:39: error:
? Couldn't match expected type ‘a’ with actual type ‘Int’
  ‘a’ is a rigid type variable bound by
    the type signature for:
      arithMean :: forall a. Fractional a => [a] -> a
    at HigherOrder.hs:9:1-39
? In the second argument of ‘(/)’, namely ‘(length list)’
  In the expression: (foldr (+) 0 list) / (length list)
  In an equation for ‘arithMean’:
      arithMean list = (foldr (+) 0 list) / (length list)
? Relevant bindings include
    list :: [a] (bound at HigherOrder.hs:10:11)
    arithMean :: [a] -> a (bound at HigherOrder.hs:10:1)

关于此错误,我很困惑为什么会迫使我将“列表”更改为[Int],我认为无论它是哪种类型,它都应该起作用

此外,我认为当我尝试使用“长度”功能时可能发生了某些事情,因为当我在下面编写此代码时,它就可以工作了

arithMean :: (Fractional a) => [a] -> a
arithMean list = (foldr (+) 0 list)

1 个答案:

答案 0 :(得分:2)

(/) :: Fractional a => a -> a -> a的类型意味着分子和分母都必须具有相同的Fractional类型。

length :: [a] -> Int但是将可折叠对象映射到IntInt不是Fractional类型的。

您可以在此处使用fromIntegral :: (Integral a, Num b) :: a -> bInt转换为Num typeclass成员的类型。

arithMean :: (Fractional a, Foldable f) => f a -> a
arithMean list = sum list / fromIntegral (length list)

我们可以在这里使用sum :: (Foldable f, Num a) => f a -> a,而不是在这里使用foldr (+) 0 list