Я изучаю Haskell. У меня есть эмпирическая функция, которая возвращает таблицу умножения до '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 принимает два параметра, реализующих плавающее типовое окно. Перед передачей их в logBase необходимо обратиться к параметрам изIntegral. Это скомпилировано для меня с 6.10.3:
nOfDg :: Int -> Int-> Int
nOfDg n base = 1 + floor ( logBase (fromIntegral base) (fromIntegral (n*n)))
Вы должны помнить, что Haskell очень сильно набран, так что вы не можете просто предполагать, что параметры Int, поставляемые в вашу функцию, будут автоматически принуждаться к плавающим числам, которые функции log обычно принимают.
.Из прелюдии :
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...), так как они часто всплывают в коде, изучение приведений может быть полезным.
Правка : эта Вики-книга Хаскелла предоставляет очень полезную графику взаимосвязи между стандартными классами типов, включая числовые типы.
.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)))