content: class Shape a where
      perimeter :: a -> Double
      area      :: a -> Double
  {- A type class Shape. Types belonging to Shape must support two
  methods, perimeter and area. -}
  
  data Rectangle = Rectangle Double Double
  {- A new type with a single constructor. In the case of data types
  which have only one constructor, we conventionally give the
  constructor the same name as the type, though this isn't mandatory. -}
  
  data Circle = Circle Double
  
  instance Shape Rectangle where
      perimeter (Rectangle width height) = 2 * width + 2 * height
      area      (Rectangle width height) = width * height
  {- We made Rectangle an instance of the Shape class by
  implementing perimeter, area :: Rectangle -> Int. -}
  
  instance Shape Circle where
      perimeter (Circle radius) = 2 * pi * radius
      area      (Circle radius) = pi * radius^2
  
  apRatio :: Shape a => a -> Double
  {- A simple polymorphic function. -}
  apRatio shape = area shape / perimeter shape
  
  main = do
      print $ apRatio $ Circle 5
      print $ apRatio $ Rectangle 5 5
  {- The correct version of apRatio (and hence the correct
  implementations of perimeter and area) is chosen based on the type
  of the argument. -}
  