Объявление экземпляра в Haskell - PullRequest
3 голосов
/ 02 февраля 2012

У меня есть две функции:

primes = sieve [2..] 
    where
        sieve (p:xs) = p : sieve [x|x <- xs, x `mod` p > 0]
isPrime number = number /= 1 && null [x | x <- takeWhile (\x -> x < (ceiling . sqrt) number) primes, mod number x == 0]

Дело в том, что когда я пытаюсь загрузить модуль, который содержит эти функции, я вижу следующее сообщение об ошибке:

[2 of 2] Compiling Main             ( euler37.hs, interpreted )

euler37.hs:6:70:
No instance for (RealFrac Int)
  arising from a use of `ceiling'
Possible fix: add an instance declaration for (RealFrac Int)
In the first argument of `(.)', namely `ceiling'
In the expression: ceiling . sqrt
In the second argument of `(<)', namely `(ceiling . sqrt) number'

euler37.hs:6:80:
No instance for (Floating Int)
  arising from a use of `sqrt'
Possible fix: add an instance declaration for (Floating Int)
In the second argument of `(.)', namely `sqrt'
In the expression: ceiling . sqrt
In the second argument of `(<)', namely `(ceiling . sqrt) number'

Я действительно не могу понять, в чем проблема, потому что, когда я пытаюсь сделать небольшую функцию из фрагмента кода, который, насколько я понимаю, вызывает эти ошибки, прямо в ghci, как пусть е число х = х <(потол. кв. м) число Я не вижу сообщений об ошибках. </p>

1 Ответ

7 голосов
/ 02 февраля 2012

Проблема в том, что primes - это список целых чисел (из-за использования вами mod), но sqrt работает с числами с плавающей запятой.Если вы сделаете x < (ceiling . sqrt . fromIntegral) number, то все будет работать нормально.fromIntegral просто преобразует целое число в любой другой числовой тип:

fromIntegral :: (Integral a, Num b) => a -> b

В этом случае, поскольку вы не указываете какой-либо конкретный тип с плавающей запятой для преобразования, по умолчанию используется Doubleзначения для вычисления квадратного корня.Вы можете указать другой тип, изменив fromIntegral на что-то вроде (fromIntegral :: Integer -> Float).

Причина, по которой вы не видите эту ошибку в GHCi, заключается в том, что с вашим условием все в порядке;он просто работает на разных типах, которые вы используете здесь.Одной проверки правильности фрагмента кода в отдельности недостаточно;для того, чтобы он прошел проверку типов, он также должен иметь смысл в контексте.

Возможно, вы захотите использовать алгоритм целочисленного квадратного корня для точности.

...