没有因使用“sqrt”而产生的(Floating Int)实例

No instance for (Floating Int) arising from a use of ‘sqrt’

关于 SO 的同名问题还有一个。我已经阅读了这里已经回答的问题,但我仍然不明白如何解决这些问题

No instance for (Fractional Int) arising from a use of ‘/’
In the expression: (a + b + c) / 2
-- and
No instance for (Floating Int) arising from a use of ‘sqrt’
In the first argument of ‘(>)’, namely

在这个简单的函数中,该函数用于计算三角形的 3 条边的面积。

----- Heron's formula -----
-- S = sqrt(p*(p-a)*(p-b)*(p-c)), where p = (a+b+c)/2

isTriangle :: Int -> Int -> Int -> Bool
isTriangle a b c = let p = (a + b + c) / 2
                   in if (sqrt(p * (p - a) * (p - b) * (p - c)) > 0)
                      then True
                      else False

感谢任何帮助和对此处错误的解释。


更新:triangle inequality 的方式中,我已经找到了(似乎是这样)解决方案。但是 "No instance for" 的问题对我来说仍然没有解决。我很想弄明白。

-- works fine
import Data.List (sort)
isTriangle :: Int -> Int -> Int -> Bool
isTriangle a b c = let sides = sort[a, b, c]
                   in if ((last sides) < head sides + (head $ tail sides))
                      then True
                      else False

您需要先将 Int 转换为浮点数,然后再计算平方根并除以 /(对于整数除法,请使用 divquot).

也可以简化您的 if ... then True else False

isTriangle :: Int -> Int -> Int -> Bool
isTriangle a b c = let a' = fromIntegral a
                       b' = fromIntegral b
                       c' = fromIntegral c
                       p = (a' + b' + c') / 2
                   in 0 < sqrt (p * (p - a') * (p - b') * (p - c'))

sqrt 函数的类型为

sqrt :: Floating a => a -> a

(它实际上是 Floating class 的一个方法)所以它适用于任何标准的基于浮点数的数值表示,包括 DoubleComplex Double 和其他不太重要的类型。它也可能适用于非标准、非浮点、非常奇特的数字表示。但是Int不支持平方根,因为只有完全平方才有整数平方根。您可能应该切换到提供它们的类型。如果您需要从 Int 个值开始,您可以将它们转换为

fromIntegral :: (Integral i, Num n) => i -> n

为了您的特定目的(弄清楚您是否有三角形),您实际上不需要计算平方根。你能看出原因吗?