[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