Ошибка типа GHC, которую я не понимаю - PullRequest
4 голосов
/ 20 августа 2009

Я учу себя Хаскеллу.

Я хочу написать функцию, которая рекурсивно находит первое число с целочисленным квадратным корнем и меньше начального числа.

Это выглядит так:

findFirstSquare :: Int -> Int
findFirstSquare x
    | x <= 0                                  = error "This function only works for 1 or above"
    | fromInteger(floor(sqrt(x))) == (sqrt x) = x
    | otherwise                               = intSqrt(x - 1)

Но GHC жалуется:

Нет экземпляра для (RealFrac Int), возникающего из-за использования `floor 'в ...

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

 fromInteger(floor(sqrt(4))) == (sqrt 4)

У меня вопрос: почему я получаю ошибку типа из выражения, которое успешно компилируется в GHCi?

1 Ответ

9 голосов
/ 20 августа 2009

Хорошо, я понял это.

Разница в том, что константа "4" перегружена, поэтому в интерактивном режиме sqrt (4) получает квадратный корень из Float 4

Однако моя функция объявляет x как Int , поэтому мне нужно было добавить fromIntegral к вызовам sqrt, чтобы они работали.

Смена среднего охранника на следующее сделала свое дело:

| fromIntegral(floor(sqrt(fromIntegral(x)))) == (sqrt(fromIntegral(x))) = x
...