{-# LANGUAGE DataKinds #-} {-# LANGUAGE TypeFamilies #-} 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 HasDataID a where getDataID :: a -> DataID getDependencies :: c a => a -> [Entity [HasDataID, c]] class GetMessage a where getMessage :: a -> Int data Foo = Foo data Bar = Bar instance GetMessage Bar where getMessage _ = 1 instance HasDataID Bar where getDataID _ = DataID getDependencies _ = [] instance HasDataID Foo where getDataID _ = DataID --getDependencies :: (c ~ getMessage) => Foo -> [Entity [HasDataID, GetMessage]] getDependencies _ = [MkEntity Bar]