yulian
yulian

Reputation: 1627

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

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

Answers (2)

dfeuer
dfeuer

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

epsilonhalbe
epsilonhalbe

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

Related Questions