{-# OPTIONS -fglasgow-exts -fallow-overlapping-instances -fallow-undecidable-instances #-}
module Test where

import Data.Typeable

-- Skeleton of the Data class
class (Typeable a, Sat (ctx a)) => Data ctx a

-- Our main class with 2 parameters
class (Data (DictClassA a) b, ClassB b) => ClassA a b where
    func :: b -> a -> String

-- The class which contrains ClassA
class ClassB a where
    func2 :: a -> String

data DictClassA a b = DictClassA { funcD :: b -> a -> String, classBD :: DictClassB b }
data DictClassB b = DictClassB { func2D :: b -> String }

class Sat a where
    dict :: a

instance Sat (ctx String) => Data ctx String

-- Trying to access any of functions in ClassA works fine, but trying to get at anything in ClassB causes and infinite loop.
instance (Data (DictClassA a) b, ClassA a b, ClassB b) => Sat (DictClassA a b) where
    dict = DictClassA { funcD = func, classBD = dict }

instance ClassB b => Sat (DictClassB b) where
    dict = DictClassB { func2D = func2 }

instance ClassA a String where
    func _ _ = "hello"

instance ClassB String where
    func2 _ = "bye"