
Hi. I won't pretend to be an advanced Haskell programmer. However, I have a strong interest in abstraction, and I have been playing around with programming as abstractly as possible. Naturally, I find classes to be quite attractive and useful. However, something is bothering me. Lately I keep running into this situation where I have to cut across abstraction layers in order to make the code work. More specifically, I keep finding that I have to add constraints to a class definition, because eventually I find some instance of that class which needs those constraints to compile. For example, I wanted to create a class which represents all things that can be converted into X,Y coordinates. Naturally, I would like to do something like this: code: -------- class XyConv a where toXy :: a b -> [Xy b] -------- This leaves me free in the future to use any number type conceivable in the Xy coordinates - Floating or Integral types, or whatever. (Doesn't even have to be numbers, actually!) However the first instance I create, requires me to use operators in the function definition which require at least a Floating type. (The error will say Fractional, but there are other components that also require Floating.) code: -------- data CircAppr a b = CircAppr a b b -- number of points, rotation angle, radius deriving (Show) instance Integral a => XyConv (CircAppr a) where toXy (CircAppr divns ang rad) = let dAng = 2 * pi / (fromIntegral divns) in let angles = map ((+ ang) . (* dAng) . fromIntegral) [0..divns] in map (\a -> am2xy a rad) angles -------- This gives me the error code: -------- Could not deduce (Fractional b) arising from a use of `/' from the context (Integral a) bound by the instance declaration at /scratch/cmhoward/pulse-spin/pulse-spin.hs:51:10-42 Possible fix: add (Fractional b) to the context of the type signature for toXy :: CircAppr a b -> [Xy b] or the instance declaration In the expression: 2 * pi / (fromIntegral divns) In an equation for `dAng': dAng = 2 * pi / (fromIntegral divns) In the expression: let dAng = 2 * pi / (fromIntegral divns) in let angles = map ((+ ang) . (* dAng) . fromIntegral) [0 .. divns] in map (\ a -> am2xy a rad) angles -------- I can get a quick fix by adding Floating to the context of the /class/ definition: code: -------- class XyConv a where toXy :: Floating b => a b -> [Xy b] -------- But what I really want is to put Floating in the context of the /instance/ declaration. But I don't know how to do that syntactically. -- frigidcode.com