In my Haskell program I have some typeclasses representing abstract notions of "shapes", namely
-- | Class representing shapes.
class Shape a where
isColliding :: (Shape b) => a -> b -> Bool
centroid :: Point
-- | Class representing shapes composed of a finite number of vertices
and line segments connecting them.
class (Shape a) => Polygon a where
vertices :: a -> Vertices
As you can see, Polygon
is naturally a subclass of Shape
. I also have some data types that are instances of these different typeclasses. For example:
data Box = Box Point Point Angle
instance Shape Box where
...
instance Polygon Box where
...
---------------------------------
data Circle = Circle Point Radius
instance Shape Circle where
...
I have many more possible shapes, such as NGon
, RegularNGon
, etc. I would like to be able to implement isColliding
, but the information required to calculate whether two shapes are colliding is dependent upon the implementation of the specific instance of Shape
. For example, to calculate if two boxes are colliding, I need their list of vertices. So I have a few questions:
- Is there anyway to "specialize" my function
isColliding
so that it is defined in a specific way for collisions of the typeisColliding :: (Polygon b) => Box -> b -> Bool
? - Is the structuring of my datatypes the best way to approach this problem, or am I misusing typeclasses and datatypes when the whole thing could be restructured to eliminate this problem?
I am rather new to Haskell, so if my question is worded poorly or any clarification is needed, please tell me.