Having typing problem with "tan" function.

Hi, I am new to Haskell, so the following problem is probably easy for you to spot but difficult for me. Any pointers would be appreciated. In GHCI on a load I am getting the following message: SSnowflake.hs:41:45: No instance for (Floating Int) arising from use of `pi' at Snowflake.hs:41:45-46 Probable fix: add an instance declaration for (Floating Int) In the first argument of `(/)', namely `pi' In the first argument of `tan', namely `(pi / 3)' In the second argument of `(*)', namely `(tan (pi / 3))' Failed, modules loaded: none. When I put the expression "tan ( pi / 3)" at the GHCI interpreter prompt I get a value, but this is not accepted on a load the code. Here is the code:
code
triangle :: Window -> (Point,Point) -> Int -> IO () triangle window ((x1,y1), (x2,y2)) size = let height = fromIntegral(y2 - y1) * 3 / 2 halfWidth = height * (tan (pi / 3 )) in drawInWindow window (withColor (sizeColorMap size) (polygon [(x1,y1),( x1 - halfWidth, height ), (x1 + halfWidth, height)] ))

The compiler is complaining that there's no instance of the Floating
class for Int because Floating is the class where pi and tan are
defined, and it manages to infer that halfWidth must be an Int. How
does it do this?
Well, assuming that you are using SOE or a similar graphics library,
the polygon function expects a list of Points, and type Point = (Int,
Int). So, in particular, x1 - halfWidth must be an Int, and so
halfWidth needs to be an Int.
Hence, you probably want to change the definition of halfWidth to be:
halfWidth = round (height * tan (pi / 3))
Also, just as a side note, your indentation is a little unusual. It's
more common to align the 'let' with the 'in'. This would also be an
appropriate place to use 'where'.
hope this helps,
- Cale
On 12/10/06, Edward Ing
Hi, I am new to Haskell, so the following problem is probably easy for you to spot but difficult for me. Any pointers would be appreciated. In GHCI on a load I am getting the following message:
SSnowflake.hs:41:45: No instance for (Floating Int) arising from use of `pi' at Snowflake.hs:41:45-46 Probable fix: add an instance declaration for (Floating Int) In the first argument of `(/)', namely `pi' In the first argument of `tan', namely `(pi / 3)' In the second argument of `(*)', namely `(tan (pi / 3))' Failed, modules loaded: none.
When I put the expression "tan ( pi / 3)" at the GHCI interpreter prompt I get a value, but this is not accepted on a load the code.
Here is the code:
code
triangle :: Window -> (Point,Point) -> Int -> IO () triangle window ((x1,y1), (x2,y2)) size = let height = fromIntegral(y2 - y1) * 3 / 2 halfWidth = height * (tan (pi / 3 )) in drawInWindow window (withColor (sizeColorMap size) (polygon [(x1,y1),( x1 - halfWidth, height ), (x1 + halfWidth, height)] ))
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe

Okay, I think I get it. The thing to realize is that if you do not declare type, Haskell, being smart makes some inferences of the type of values depending on the expression and usage of the value. To solve the problem I tested a variation based on this understanding and it seems to have worked. I declared type for the expressions. Thanks for the help and the comment about the indenting. (Indenting is a little confusing at this point.) triangle :: Window -> (Point,Point) -> Int -> IO () triangle window ((x1,y1), (x2,y2)) size = let height :: Float height = fromIntegral(y2 - y1) * 3 / 2 halfWidth :: Float halfWidth = height * (tan (pi / 3 )) in drawInWindow window (withColor (sizeColorMap size) (polygon [(x1,y1),( x1 - (round halfWidth), round height ), (x1 + (round halfWidth), round height)] )) On Thu, 2006-12-10 at 20:45 -0400, Cale Gibbard wrote:
The compiler is complaining that there's no instance of the Floating class for Int because Floating is the class where pi and tan are defined, and it manages to infer that halfWidth must be an Int. How does it do this?
Well, assuming that you are using SOE or a similar graphics library, the polygon function expects a list of Points, and type Point = (Int, Int). So, in particular, x1 - halfWidth must be an Int, and so halfWidth needs to be an Int.
Hence, you probably want to change the definition of halfWidth to be: halfWidth = round (height * tan (pi / 3))
Also, just as a side note, your indentation is a little unusual. It's more common to align the 'let' with the 'in'. This would also be an appropriate place to use 'where'.
hope this helps, - Cale
On 12/10/06, Edward Ing
wrote: Hi, I am new to Haskell, so the following problem is probably easy for you to spot but difficult for me. Any pointers would be appreciated. In GHCI on a load I am getting the following message:
SSnowflake.hs:41:45: No instance for (Floating Int) arising from use of `pi' at Snowflake.hs:41:45-46 Probable fix: add an instance declaration for (Floating Int) In the first argument of `(/)', namely `pi' In the first argument of `tan', namely `(pi / 3)' In the second argument of `(*)', namely `(tan (pi / 3))' Failed, modules loaded: none.
When I put the expression "tan ( pi / 3)" at the GHCI interpreter prompt I get a value, but this is not accepted on a load the code.
Here is the code:
code
triangle :: Window -> (Point,Point) -> Int -> IO () triangle window ((x1,y1), (x2,y2)) size = let height = fromIntegral(y2 - y1) * 3 / 2 halfWidth = height * (tan (pi / 3 )) in drawInWindow window (withColor (sizeColorMap size) (polygon [(x1,y1),( x1 - halfWidth, height ), (x1 + halfWidth, height)] ))
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe

Am Freitag, 13. Oktober 2006 02:22 schrieb Edward Ing:
Hi, I am new to Haskell, so the following problem is probably easy for you to spot but difficult for me. Any pointers would be appreciated. In GHCI on a load I am getting the following message:
SSnowflake.hs:41:45: No instance for (Floating Int) arising from use of `pi' at Snowflake.hs:41:45-46 Probable fix: add an instance declaration for (Floating Int) In the first argument of `(/)', namely `pi' In the first argument of `tan', namely `(pi / 3)' In the second argument of `(*)', namely `(tan (pi / 3))' Failed, modules loaded: none.
When I put the expression "tan ( pi / 3)" at the GHCI interpreter prompt I get a value, but this is not accepted on a load the code.
Here is the code:
code
triangle :: Window -> (Point,Point) -> Int -> IO () triangle window ((x1,y1), (x2,y2)) size = let height = fromIntegral(y2 - y1) * 3 / 2 halfWidth = height * (tan (pi / 3 )) in drawInWindow window (withColor (sizeColorMap size) (polygon [(x1,y1),( x1 - halfWidth, height ), (x1 + halfWidth, height)] ))
The co-ordinates must have type Int, I believe, tan has type Floating a => a -> a. However, Int is not an instance of the Floating class. What you ought to do is convert height and halfWidth to Int via round, floor or ceiling. Then it should work. Cheers, Daniel
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
participants (3)
-
Cale Gibbard
-
Daniel Fischer
-
Edward Ing