Let a module to abstract Area
operations (bad definition)
class Area someShapeType where
area :: someShapeType -> Float
-- module utilities
sumAreas :: Area someShapeType => [someShapeType]
sumAreas = sum . map area
Let a posteriori explicit shape type modules (good or acceptable definition)
data Point = Point Float Float
data Circle = Circle Point Float
instance Surface Circle where
surface (Circle _ r) = 2 * pi * r
data Rectangle = Rectangle Point Point
instance Surface Rectangle where
surface (Rectangle (Point x1 y1) (Point x2 y2)) = abs $ (x2 - x1) * (y2 - y1)
Let some data
c1 = Circle (Point 0 0) 1
r1 = Rectangle (Point 0 0) (Point 1 1)
Then, trying to use
totalArea = sumAreas [c1, r1]
the [c1, r1]
type must be expanded to [Circle]
or [Rectangle]
! (and is not valid)
I can do using forall
and a extra data
type like this
data Shape = forall a . Surface a => Shape a
sumSurfaces :: [Shape] -> Float
sumSurfaces = sum . map (\(Shape x) -> surface x)
then, next code run successfully
sumSurfaces [Shape c1, Shape r1]
but I think, the use of data Shape
and Shape
constructor (on [Shape c1, ...]
and lambda argument) is ugly (my first [and bad] way is pretty).
What is the correct way to do "Heterogeneous polymorphism in Haskell"?
Thank you very much for your time!
data Shape
the correct way? – Signatureclass Area
likeclass Surface a => Area a where area = surface
? – Selfesteem