{-# LANGUAGE ExistentialQuantification #-} data Square = Square Int data Circle = Circle Int data Rectangle = Rectangle Int Int class HasArea a where area :: a -> Double instance HasArea Square where area (Square n) = fromIntegral n * fromIntegral n instance HasArea Circle where area (Circle r) = pi * fromIntegral r instance HasArea Rectangle where area (Rectangle n m) = fromIntegral n * fromIntegral m data Shape = forall s. HasArea s => Shape s shapes :: [Shape] shapes = [Shape (Square 5), Shape (Circle 2), Shape (Rectangle 10 5)] shapeArea :: Shape -> Double shapeArea (Shape s) = area s main = print $ map shapeArea shapes