{-# LANGUAGE MultiParamTypeClasses, FlexibleInstances #-}

-- This is a superclass loop test
-- It should fail with a type error, but
-- it's all too easy to succeed with a bogus recursive dictionary

module SCLoop where

class SC a where 
  f :: a -> ()

class SC a => A a b where 
  op :: a -> b -> ()
  op x _ = f x

instance A a b => A a [b]
-- dfun1 :: \d::(A a b) -> DA (sc d)

instance SC a  => A a (Maybe b)
-- dfun2 :: \d::SC a -> DA d

foo = op () ([Just True])

{- Here is the explanation: 
~~~~~~~~~~~~~~~~~~~~~~~~~~~

[Wanted]  d1 : (A () [Maybe Bool])
~~~>                              d1 := dfun1 d2 
[Wanted]  d2 : (A () (Maybe Bool))
~~~>                              d2 := dfun2 d3 
[Wanted]  d3 : SC ()
[Derived] d4 : SC ()               d4 := sc d1
~~~> 
      d3 := sc d1
      isGoodRecEv will check: 
                  d3 == sc d1 
                     == sc (dfun1 d2) 
                     == sc (dfun1 (dfun2 d3) ==> PASSES!   (gravity = 1)
        This is BAD BAD BAD, because we get a loop

      If we had inlined the definitions:
                  d3 == sc d1 
                     == sc (DA (sc d2))
                     == sc (DA (sc (DA d3))) ==> DOES NOT! (gravity = 0)

We should get "No instance for SC ()"
-}








