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
I don't have GHC 7.0.3 available, but I think this should work with it.
You could pass the dictionaries around manually like this (using Context
= Show
as an example):
{-# LANGUAGE ScopedTypeVariables, TypeFamilies, ExistentialQuantification #-}
data ShowDict a = Show a => ShowDict
class Class a where
data Associated a :: * -> *
getShow :: ShowDict (Associated a b)
-- Convenience function
getShowFor :: Class a => Associated a b -> ShowDict (Associated a b)
getShowFor _ = getShow
showAssociated :: Class a => Associated a b -> String
showAssociated a =
case getShowFor a of
ShowDict -> -- Show (Associated a b) is made available by this pattern match
show a
instance Class Int where
data Associated Int b = Foo deriving Show
getShow = ShowDict
main = print $ showAssociated Foo
This is somewhat similar to the function copying you propose, but advantages are:
showAssociateds :: forall a b. Class a => [Associated a b] -> String
showAssociateds as =
case getShow :: ShowDict (Associated a b) of
ShowDict ->
show as
The main disadvantage is that using getShow
always requires an explicit type signature (functions like getShowFor
can mitigate this).