
Idiomatic Haskell for *drawing* shapes is to represent Shapes as functions from their origin to what they draw (e.g. Bitmap). type Drawing = Pt2 -> Bitmap -- Circle needs a radius type Circle = Float -> Drawing circle :: Circle circle r = \pt -> {...} -- Rect needs width and height type Rect = Float -> Float -> Drawing rect :: Rect rect w h = \pt -> {...} Transformations like scaling work by pre-transforming the arguments uniform_scale_rect :: Float -> Rect uniform_scale_rect sz = \w h -> rect (sz*w) (sz*h) uniform_scale_scale :: Float -> Circle uniform_scale_scale sz = \r -> cicle (sz*r) If you want a polymorphic scale function you will have to make your shapes individual newtypes so us can write specific instances for them. This works very well for drawing, but because Shapes are represented as functions they cannot support introspection e.g. querying a circle for its radius. Depending how you design your editor you might find introspection wasn't a genuine requirement.