ошибка типа при создании списка из целочисленного типа - PullRequest
1 голос
/ 31 марта 2019

Я пытаюсь реализовать простую функцию: totient:

coprime :: Integral a => a -> a -> Bool
coprime a b = gcd a b == 1

totient :: Integral a => a -> a
totient m = length $ filter (coprime m) [1..m-1]

ghci> :load 99problems.hs
[1 of 1] Compiling Main             ( 99problems.hs, interpreted )

99problems.hs:250:13: error:
    • Couldn't match expected type ‘a’ with actual type ‘Int’
      ‘a’ is a rigid type variable bound by
        the type signature for:
          totient :: forall a. Integral a => a -> a
        at 99problems.hs:249:12
    • In the expression: length $ filter (coprime m) [1 .. m - 1]
      In an equation for ‘totient’:
          totient m = length $ filter (coprime m) [1 .. m - 1]
    • Relevant bindings include
        m :: a (bound at 99problems.hs:250:9)
        totient :: a -> a (bound at 99problems.hs:250:1)
Failed, modules loaded: none.

Я пытался использовать такие вещи, как fromIntegral или toInteger на (m-1), но ничего из этого не помогло. Я не уверен, что мне здесь не хватает ... похоже, что Int должно быть типа Integral a => a. Что не так?

1 Ответ

5 голосов
/ 31 марта 2019

Тип Integral a => a -> a говорит:

  1. Абонент получает возможность выбрать тип a.
  2. Абонент должен доказать, что a является экземпляром Integral.
  3. Вызывающая сторона должна предоставить значение типа a.
  4. Разработчик создает другое значение типа a.

Однако в этом случае реализаторпроизвел Int.Каждый раз, когда вызывающий абонент выбирает a в качестве экземпляра Integral, который не является Int, это не будет соответствовать типу вызывающего абонента.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...