Haskell получает sqrt от Int
Как я могу получить sqrt
от Int
.
Я стараюсь:
sqrt . fromInteger x
Но получите ошибку при совместимости типов.
Ответы
Ответ 1
Использование fromIntegral
:
Prelude> let x = 5::Int
Prelude> sqrt (fromIntegral x)
2.23606797749979
оба Int
и Integer
являются экземплярами Integral
:
-
fromIntegral :: (Integral a, Num b) => a -> b
принимает ваш Int
(который является экземпляром Integral
) и "делает" его Num
.
-
sqrt :: (Floating a) => a -> a
ожидает, что Floating
и Floating
наследуют от Fractional
, который наследует от Num
, поэтому вы можете безопасно перейти к sqrt
результату fromIntegral
Я думаю, что классы диаграмма в Haskell Wikibook в этом случае весьма полезен.
Ответ 2
Возможно, вы хотите, чтобы результат был также Int
?
isqrt :: Int -> Int
isqrt = floor . sqrt . fromIntegral
Вы можете заменить floor
на ceiling
или round
.
(BTW, эта функция имеет более общий тип, чем тот, который я дал.)
Ответ 3
Помните, что приложение связывается более жестко, чем любой другой оператор. Это включает в себя композицию. Вы хотите
sqrt $ fromIntegral x
Тогда
fromIntegral x
будет оцениваться первым, поскольку неявное приложение (космос) связывается более жестко, чем явное приложение ($).
В качестве альтернативы, если вы хотите увидеть, как будет работать композиция:
(sqrt . fromIntegral) x
Скобки сначала проверяют, что оператор композиции оценивается, а затем результирующая функция - в левой части приложения.