content: {-# LANGUAGE FlexibleContexts #-}
  
  import Prelude hiding (Semigroup(..))
  
  {-
  [Summary of the program] Ring is defined as a subclass of Semigroup,
  inheriting multiplication.  Additive is a wrapper that extracts the additive
  structure of Ring and reifies it as Semigroup.  For simplicity, the code omits
  ring operations (+ and *) and defines only the additive and multiplicative
  identities.
  
  [The bug] If there is a cyclic class hierarchy like
  
      class B a => Semigroup a                  where ...
      class Semigroup (Additive a) => Ring a    where ...
      instance Ring a => Semigroup (Additive a) where ...
  
  then uses of B's methods on (Additive a) in the method implementations of the
  third declaration "instance Ring a => Semigroup (Additive a)" will:
  
      1. be accepted by the compiler even in cases where B (Additive a) is not
         derivable.
      2. result in <<loop>>.
   -}
  
  class B a where
      b :: a
  class B a => Semigroup a where
      unit :: a
  class (Semigroup a, Semigroup (Additive a)) => Ring a where
      zero :: a
  newtype Additive a = Additive a
  
  -- The source compiles whether with or without this instance declaration in GHC
  -- 7.2.1 - 7.4.1 and produces <<loop>>.
  --
  -- GHC 7.0.4 rejects this source without this declaration and produces
  -- terminating code with the declaration.
  instance B a => B (Additive a) where
     b = Additive b
  
  instance Ring a => Semigroup (Additive a) where
      unit = b -- Use a method of type (B a => ...) with a instantiated as
               -- (Additive a).  This causes <<loop>>.
  
  
  -- Now try to instantiate Ring and evaluate `unit'.
  instance B Int where
      b = 1234567890
  instance Semigroup Int where
      unit = 1
  instance Ring Int where
      zero = 0
  main = case (unit :: Additive Int) of -- Force the additive identity of Int.
           Additive x -> print x
  