Class constraints for associated type synonyms

Brandon Moore brandon_m_moore at yahoo.com
Thu Mar 24 04:22:00 CET 2011


> From: Jan-Willem Maessen <jmaessen at alum.mit.edu>

> Sent: Wed, March 23, 2011 8:43:14 PM
> 
> 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:
> 
>   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.

The conditions in the report are quite restrictive - in particular, the context
must consist only of classes applied to type variables. When you used a
multiparameter type class and an FD, the type you wanted to mention was
just a type variable.

http://www.haskell.org/onlinereport/haskell2010/haskellch4.html#x10-750004.3

The GHC user's guide suggests FlexibleContexts should be enough to allow
you to declare that class:

http://www.haskell.org/ghc/docs/7.0-latest/html/users_guide/type-class-extensions.html


FlexibleInstances seems only to affect what is allowed in an instance head.
I don't see how it helps at all, unless it implies some other extensions.

You might still run into termination issues - as a an associated type synonym
rather than an associated data type, GeneratorOf a might very well be something
large, and the conditions (disabled by UndecidableInstances) don't take 
advantage
of the acyclic superclass relationship.

http://www.haskell.org/ghc/docs/7.0-latest/html/users_guide/type-class-extensions.html#instance-rules


> 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.

Do you have any examples? I've always found FlexibleInstances alone
unproblematic - it's only when you add OverlappingInstances or worse
that things can get messy.
 
Brandon



      



More information about the Glasgow-haskell-users mailing list