{-# LANGUAGE DataKinds, TypeFamilies, FunctionalDependencies #-} module Main where import Data.Kind (Type) data Tag = A | B | C data STag tag where SA :: STag A SB :: STag B SC :: STag C -- class Fam (tag :: Tag) (t :: Type) | tag -> t where -- instance {-# OVERLAPPABLE #-} Fam a Bool where -- instance {-# INCOHERENT #-} Fam A Int where type family Fam tag where Fam A = Int Fam _ = Bool class Foo (tag :: Tag) where foo :: STag tag -> Fam tag instance {-# OVERLAPPABLE #-} Fam tag ~ Bool => Foo tag where foo _ = True instance Foo A where foo _ = 42 main = do print $ foo SA print $ foo SB print $ foo SC -- foo :: forall tag a. STag tag -> Fam tag -- foo SA = 42 :: Int -- foo _ = True :: Bool