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