Reputation: 1627
One more question on SO with the same title. I've read already answered questions here but still I don't understand how can I solve these
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
in this simple function that is for finding the area of a triangle by 3 sides.
----- 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
Any help and explanation of what is wrong here is appreciated.
update: In the way of triangle inequality i've got working (seems to be so) solution. But the issue with "No instance for" is still unresolved for me. I do want to figure it out.
-- 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
Upvotes: 1
Views: 2093
Reputation: 48591
The sqrt
function has type
sqrt :: Floating a => a -> a
(it's actually a method of the Floating
class) so it works for any standard floating point-based numerical representation, including Double
, Complex Double
, and other, less important, types. It likely also works for non-standard, non-floating-point, very fancy numerical representation. But Int
does not support square roots, because only perfect squares have integral square roots. You should probably switch to a type that offers them. If you need to start from Int
values, you can convert them with
fromIntegral :: (Integral i, Num n) => i -> n
For your particular purpose (figuring out if you have a triangle at all), you don't actually need to calculate the square root. Can you see why?
Upvotes: 8
Reputation: 15967
you need to convert the Int
to a floating point number before calculating the square root and before dividing it with /
(for integer division use div
or quot
).
Also one can simplify your 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'))
Upvotes: 2