
If however, you *really* want to keep your shapes as being seperate types, then you'll want to invoke the class system (note, not the same as OO classes).
class Shape a where area :: a -> Int
newtype Circle = C Int
instance Shape Circle where area (C r) = pi * r^2
newtype Rectangle = R Int Int
instance Shape Rectangle where area (R h w) = h * w
newtype Square = Sq Int
instance Shape Square where area (Sq l) = l * l
-- Now we can do something with our shapes doubleArea :: Shape a => a -> Int doubleArea s = (area s) * 2
Perhaps introduce an existensial quantification? data Shape = forall a. Sh a => Shape a class Sh a where area :: a -> Float data Circle = Circle Float instance Sh Circle area (Circle r) = pi*r*2 data Rect = Rect Float Float instance Sh Rect area (Rect h w) = h * w doubleArea :: Shape -> Float doubleArea (Shape x) = (area x) * 2 I think this is more in the traditional OOP sense. But this way or Tom's: one would have to convert functions like equality over Values of type Shape into equality over different types (Circle and Rect). This can be done using case analysis over the types with something like read. Kind regards, Chris.