I would like to state that the associated data is always an instance of a certain class.
class (Context (Associated a b)) => Class a where
data Associated a
As was pointed out by @SjoerdVisscher, using forall
on the left side of =>
in a class
or instance
is actually not ok, at least not yet, though my specific example does work in ghc-7.4.
This way it seems to work:
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE Rank2Types #-}
{-# LANGUAGE ConstraintKinds #-}
{-# LANGUAGE UndecidableInstances #-}
class Context c where
func1 :: c -> String
class (forall b. Context (Associated a b)) => Class a where
data Associated a :: * -> *
newtype ClassTest = ClassTest { runClassTest :: String }
instance (forall b. Context (Associated ClassTest b)) => Class ClassTest where
data Associated ClassTest b = ClassTestAssoc b (b -> ClassTest)
instance Context (Associated ClassTest b) where
func1 (ClassTestAssoc b strFunc) = runClassTest $ strFunc b
main = putStr . func1 $ ClassTestAssoc 37 (ClassTest . show)
The extra forall b
constraint in the instance seems a bit ugly and redundant, but apparently it's necessary.
$ runghc-7.4.1 tFamConstraint0.hs
37