Простая факториальная функция Haskell не компилируется

#haskell #compiler-errors #ghci

#haskell #ошибки компилятора #ghci

Вопрос:

Итак, у меня есть эта простая функция Haskell:

 fact :: (Num a) => a -> a
fact 0 = 1
fact n = n * fact (n - 1)
  

и когда я пытаюсь скомпилировать ее с помощью GHCi, я получаю сообщение об ошибке:

 test.hs:2:6: error:
    • Could not deduce (Eq a) arising from the literal ‘0’
      from the context: Num a
        bound by the type signature for:
                   fact :: Num a => a -> a
        at test.hs:1:1-25
      Possible fix:
        add (Eq a) to the context of
          the type signature for:
            fact :: Num a => a -> a
    • In the pattern: 0
      In an equation for ‘fact’: fact 0 = 1
Failed, modules loaded: none.
  

Послушайте, я знаю, что существует лучший способ написания этой функции, но мне все равно. Я просто хочу, чтобы эта функция была скомпилирована. Я не могу этого сделать. У меня сложилось впечатление, что если что-то является числом, оно должно быть экземпляром уравнения a , и поэтому предложение компилятора о возможном исправлении неверно.

Как я могу заставить этот код скомпилироваться?

Комментарии:

1. Используйте предложенное компилятором исправление.

Ответ №1:

Ваше предположение о том, что тип, который является экземпляром Num , также должен быть экземпляром Eq , является ложным. Рассмотрим предполагаемый тип для вашей функции:

 > fact 0 = 1; fact n = n * fact (n - 1)
> :t fact
fact :: (Num t, Eq t) => t -> t
  

Чтобы быть экземпляром Num , типу нужно только определить следующие функции:

  • ( )
  • (*)
  • abs
  • signum
  • fromInteger
  • либо negate или (-)

Комментарии:

1. Однако предположение верно в соответствии с Haskell 2010. GHC решил изменить его несколько версий назад.

2. Имеет смысл; 5 «встроенных» типов Word , Integer , Int , Float , и Double у которых есть Num экземпляр, у всех Eq также есть экземпляр, и я не могу придумать пример типа, для которого вам нужен только Num экземпляр.

3. Я бы хотел расширить свой ответ, но, похоже, я не могу загрузить haskell.org с моего компьютера, и, похоже, это какая-то непонятная проблема с истекшим сроком действия сертификата, которую я не могу отладить прямо сейчас. Есть ли какая-либо причина, по которой GHC изменил это?