Как понять, что это ошибка класса типа, говорящая мне, что я использую неправильный тип? - PullRequest
2 голосов
/ 08 июня 2019

Это моя функция вычисления среднего числа в списке чисел

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 Ответ

2 голосов
/ 08 июня 2019

Тип (/) :: Fractional a => a -> a -> a означает, что числитель и знаменатель должны быть одинаковыми Fractional тип.

length :: [a] -> Int однако отображает сгиб на Int. Int имеет тип , а не Fractional.

Вы можете использовать fromIntegral :: (Integral a, Num b) :: a -> b здесь, чтобы преобразовать Int в тип, который является членом Num тип, класс.

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

Вместо использования foldr (+) 0 list здесь мы можем использовать sum :: (Foldable f, Num a) => f a -> a здесь.

...