Class constraints for associated type synonyms

Jan-Willem Maessen jmaessen at
Thu Mar 24 02:43:14 CET 2011

Hi all -

I've been trying to construct a class declaration with an associated
type synonym, but I'd like to constrain that type to belong to a
particular class.

Consider the following class:

class Monoid m => Constructs c m | c -> m where
  construct :: m -> c

This captures the idea that the collection c ought to be constructed
using the monoid m (say if we're doing the construction using the
Writer monad)--the functional dependency indicates the desire for the
type c to injectively determine the choice of monoid m.  For example:

newtype ListBuilder a = Builder ([a] -> [a]) deriving (Monoid)

instance Constructs [a] (ListBuilder a) where
  construct (Builder f) = f []

instance (Ord a) => Constructs (Set a) (Set a) where
  construct = id

Now I'd like to be able to do the same thing using an associated type
synonym, something like this:

class Monoid (GeneratorOf a) => Generable a where
  type GeneratorOf a :: * -> *
  construct :: GeneratorOf a -> a

Now, it seems I need FlexibleInstances to do this when I'm using an
associated type synonym, but I don't need the flexibility when using a
multiparameter type class.  In both cases the instance constraint
involves types that can be injectively inferred (if I have my
terminology straight; work with me here) from a single type mentioned
in the class head.  In particular, I can imagine storing the
dictionary for Monoid (GeneratorOf a) in the dictionary for Generable
a, and thus allowing context reduction of (Monoid (GeneratorOf tyvar))
to (Generable tyvar).  Meanwhile, I think there are things that are
permitted by FlexibleInstances that I'd rather *not* have creeping
into my programs.

Is there a fundamental constraint I'm missing here that requires the
full generality of FlexibleInstances?  Do I need to use
FlexibleInstances whenever I use associated types in my programs?

-Jan-Willem Maessen

More information about the Glasgow-haskell-users mailing list