Frederick LI
Frederick LI

Reputation: 49

No instance for (Floating Int) (Fractional Int)

Here is part of my code:

sqa = a*a 
sqb = b*b
endX = (/) (fromIntegral sqa) (sqrt (fromIntegral (sqa + sqb)))

and both a and b are Int. However, after I use fromIntegral on it, it still shows errors No instance for (Floating Int) arising from a use of 'sqrt' and No instance for (Fractional Int) arising from a use of '/'. I don't know why this happens. Can anyone help me?

More context:

ellipse :: (Int, Int) -> Int -> Int -> [(Int, Int), Double]
ellipse (xc, yc) a b = plotEllipse1 (xc, yc, xi, yi, di1)
where
   sqa = a*a
   sqb = b*b
   xi = 0
   yi = b
   di1 = 2*sqb - 2*b*sqa + sqa
   endX = (/) (fromIntegral sqa) (sqrt (fromIntegral (sqa + sqb)))
   plotEllipse1 :: (Int, Int, Int, Int, Int) -> Raster
   plotEllipse1 (x0, y0, curX, curY, curD)
     | curX > endX  = plotEllipse2 (xc, yc, curX, curY, di2)
     | otherwise = ...

Upvotes: 1

Views: 129

Answers (1)

Chai T. Rex
Chai T. Rex

Reputation: 3007

plotEllipse1 takes a tuple of Ints:

plotEllipse1 :: (Int, Int, Int, Int, Int) -> Raster

curX is one of the elements of the tuple, so it's an Int:

plotEllipse1 (x0, y0, curX, curY, curD)

You compare curX to endX using >:

  | curX > endX  = plotEllipse2 (xc, yc, curX, curY, di2)

> is type Ord a => a -> a -> Bool, which means that the left and right sides must be the same type.

endX's type is in the Fractional and Floating typeclasses because you use sqrt and / to obtain it. But remember, the left and right sides of > must be the same type, so curX has to also have a type with those typeclasses, but its type, Int, definitely isn't part of those typeclasses, which the error messages are complaining about.

So, how do we fix this? We convert curX to endX's type:

  | fromIntegral curX > endX  = plotEllipse2 (xc, yc, curX, curY, di2)

Now fromIntegral curX should have the appropriate type.


Notice also that you've used fromIntegral elsewhere. You simply missed it in one more place it was needed.

You may also need to give endX a type signature so that the compiler knows which Fractional and Floating type you want to use. For example, Double is a perfectly good candidate, so maybe you'll use:

endX :: Double
endX = (/) (fromIntegral sqa) (sqrt (fromIntegral (sqa + sqb)))

Upvotes: 3

Related Questions