{-# LANGUAGE DataKinds #-} {-# LANGUAGE TypeFamilies, FunctionalDependencies, UndecidableSuperClasses #-} import Data.Kind main :: IO () main = pure () data Entity (cs :: [Type -> Constraint]) = forall a. All cs a => MkEntity a type family All (cs :: [Type -> Constraint]) (a :: Type) :: Constraint where All (c ': cs) a = (c a, All cs a) All '[] a = () data DataID = DataID class All cs a => HasDataID cs a | a -> cs where getDataID :: a -> DataID getDependencies :: a -> [Entity (HasDataID cs:cs)] class GetMessage a where getMessage :: a -> Int data Foo = Foo data Bar = Bar instance GetMessage Bar where getMessage _ = 1 instance HasDataID '[GetMessage] Bar where getDataID _ = DataID getDependencies _ = [] instance HasDataID '[GetMessage] Foo where getDataID _ = DataID --getDependencies :: (c ~ getMessage) => Foo -> [Entity [HasDataID, GetMessage]] getDependencies _ = [MkEntity Bar]