在Haskell中从整数获取平方根

34

我怎样从Int中获取sqrt

我尝试过以下代码:

sqrt . fromInteger x

但是由于类型不兼容出现了错误。

3个回答

53

也许你希望结果也是一个 Int 类型的?

isqrt :: Int -> Int
isqrt = floor . sqrt . fromIntegral

您可能希望将floor替换为ceilinground。(顺便说一句,这个函数比我给出的函数类型更通用。)


3
GHC会发出警告,因为它不知道在fromIntegralfloor之间应该使用哪种类型(可能是DoubleFloat等)。为了解决这个问题:isqrt x = floor . sqrt $ (fromIntegral x :: Float),虽然这种写法不够优雅。 - Pontus Granström
我喜欢它,无论如何。 GHC 8 上没有警告。 - Manoel Vilela
如果使用了-Wtype-defaults-Werror=type-defaults,ghc会发出警告。 - Abhijit Sarkar

50

使用 fromIntegral:

Prelude> let x = 5::Int
Prelude> sqrt (fromIntegral  x)
2.23606797749979

IntInteger都是Integral的实例:

  • fromIntegral :: (Integral a, Num b) => a -> b将你的Int(它是Integral的一个实例)转换为Num

  • sqrt :: (Floating a) => a -> a需要一个Floating,而Floating继承自Fractional,后者继承自Num,因此你可以安全地将fromIntegral的结果传递给sqrt

我认为Haskell Wikibook中的图表在这种情况下非常有用。


2
sqrt (fromIntegral x) 可以写成 sqrt $ fromIntegral x 吗? - rzetterberg
1
确实可以,因为显式应用($)的绑定程度不如隐式应用紧密。 - Edward
2
甚至可以使用 sqrt . fromIntegral $ x - pat
51
我更喜欢将其写为((((($)))((sqrt))(fromIntegral (x)))) - Thomas Eding

13

记住,应用比任何其他运算符都要更紧密地绑定。这包括组合。你想要的是

sqrt $ fromIntegral x
那么。
fromIntegral x 

因为隐式应用(空格)的绑定比显式应用($)更紧密,所以将首先进行评估。

或者,如果你想看看如何使用组合:

(sqrt .  fromIntegral) x

括号确保组合操作符首先被评估,然后生成的函数是应用的左侧。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接