Нет экземпляра для (Floating Int)
Вопрос
Я изучаю Хаскель.Я создал функцию, которая возвращает таблицу умножения до «n» в базе «b».Числа дополняются до цифр «w».В качестве последнего шага я хочу автоматически вычислить «w».Почему это не компилируется?
-- Number of digits needed for the multiplication table n*n in base 'base'
nOfDg :: Int -> Int-> Int
nOfDg n base = 1 + floor ( logBase base (n*n))
ошибка:
No instance for (Floating Int)
arising from a use of `logBase' at C:\haskel\dgnum.hs:4:24-38
Possible fix: add an instance declaration for (Floating Int)
In the first argument of `floor', namely `(logBase b (n * n))'
In the second argument of `(+)', namely `floor (logBase b (n * n))'
In the expression: 1 + floor (logBase b (n * n))
Решение
logBase принимает два параметра, которые реализуют класс плавающих типов.Вам нужно будет вызвать fromIntegral параметры, прежде чем передавать их в logBase.Это скомпилировано для меня с 6.10.3:
nOfDg :: Int -> Int-> Int
nOfDg n base = 1 + floor ( logBase (fromIntegral base) (fromIntegral (n*n)))
Вы должны помнить, что Haskell очень строго типизирован, поэтому вы не можете просто предполагать, что параметры Int, передаваемые в вашу функцию, будут автоматически приведены к плавающим числам, которые обычно принимают функции журналирования.
Другие советы
logBase
объявлено, что он работает с типами с плавающей запятой.Int не является типом с плавающей запятой, и существует нет автоматического преобразования в Haskell.Попробуй это:
-- Number of digits needed for the multiplication table n*n in base 'base'
nOfDg :: Int -> Float -> Int
nOfDg n base = 1 + floor (logBase base (fromIntegral (n*n)))
Из прелюдии:
logBase :: Floating a => a -> a -> a
Это означает, что при использовании logBase вы должны использовать плавающий тип.Но Int не является плавающим типом, и для числовых типов не существует автоматического преобразования, поэтому вам придется преобразовать его из Int в плавающий тип:
nOfDg n base = 1 + floor ( logBase (toEnum base) (toEnum n))
функция toEnum принимает в качестве параметра int и возвращает тип «Enum».Хорошая часть заключается в том, что Float является экземпляром Enum, поэтому вы можете использовать его.
toEnum :: Enum a => Int -> a
Вам следует прочитать/задокументировать классы стандартных типов в Haskell для числовых типов (Num, Fractional, Integral, Floating...), поскольку они часто всплывают в коде, поэтому изучение преобразований может оказаться полезным.
Редактировать :этот Книга Haskell Wiki предоставить очень полезную графику взаимоотношений между стандартными классами типов, включая числовые типы.