[Haskell-cafe] rip in the class-abstraction continuum

Christopher Howard christopher.howard at frigidcode.com
Mon May 20 07:16:38 CEST 2013


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

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 555 bytes
Desc: OpenPGP digital signature
URL: <http://www.haskell.org/pipermail/haskell-cafe/attachments/20130519/5d9cd815/attachment.pgp>


More information about the Haskell-Cafe mailing list