
Hi Claus,
What you describe is exactly how I would *want* things to work. It's
nice to hear my wishes echoed from a user perspective. :-)
On Wed, Jun 10, 2009 at 4:43 PM, Claus Reinke
just a few comments from a user (who would really, really, like to be able to define pragma collections, so that he doesn't have to switch on half a dozen separate extensions every time;-).
The following toy program requires MultiParamTypeClasses OR FlexibleContexts in order to be accepted by GHC(i):
f :: (T a b) => a -> Int f _ = 0
This of course assumes that we import the definition of T, we *must* have MultiParamTypeClasses enabled if we want to declare T. Both extensions thus enable classes with more than one argument to appear in contexts.
Only MultiParamTypeClasses does (and neither extension is needed in the module defining 'f', if 'T' is imported, which suggests that MultiParamTypeClasses is propagated to importers - this isn't true for most other extensions). The documentation still points to -fglasgow-exts, so it doesn't seem to answer these questions..
Right you are - which seems very strange to me. GHC accepts the module defining 'f' with no flags at all, even though it is clearly not Haskell 98. I'd go so far as to say that's a bug (as opposed to just unwanted/unexpected behavior).
f :: (T a ()) => a -> Int f _ = 0
i.e. changing the second argument to T to () instead, means we now *must* have FlexibleInstances, in order to allow the non-tyvar argument. This is nothing surprising, this is what FlexibleInstances are supposed to do.
You mean FlexibleContexts.
Indeed I do.
Now, FlexibleInstances *also* lifts the restriction on contexts, just like FlexibleContexts - but *only* for the contexts of instance declarations.
No. FlexibleInstances is about instance *heads*, FlexibleContexts is about contexts everywhere (in practice, there are some bugs;-).
Right, this is exactly what I *want* should happen, both as a user and as an implementor, but that's not how GHC does it. FlexibleInstances do enable FlexibleContexts for contexts in instance declarations - which I think is a wart.
class T a b -- requires MultiParamTypeClasses instance T a a -- requires FlexibleInstances instance Eq () => T a [b] -- requires FlexibleContexts instance Eq [a] => T a b -- requires UndecidableInstances
Agreed - but here you avoid the tricky cases like my 'f' above. ;-) What I would want, and what I believe you want as well, is the following: ======================================== ** MultiParamTypeClasses: Enables more than one parameter in class declarations, instance heads and more than one argument to class assertions in contexts everywhere. Formally, it would mean the following changes to the Haskell 98 syntax: topdecl -> class [scontext =>] tycls tyvar1 ... tyvarn [where cdecls] (n >=1) | instance [scontext =>] qtycls inst1 ... instn [where idecls] (n >=1) context -> class | ( class1 , ... , classn ) (n>=0) class -> qtycls cls1 ... clsn (n>=1) cls -> tyvar | ( tyvar atype1 ... atypen ) (n>=1) scontext -> simpleclass | ( simpleclass1 , ... , simpleclassn ) (n>=0) simpleclass -> qtycls scls1 ... sclsn (n>=1) scls -> tyvar ** FlexibleContexts: Enables the use of non-tyvar (or tyvar applied to types) arguments to class assertions in contexts everywhere (orthogonal to whether there can be several arguments or just one). Formally it means the following syntactic changes to Haskell 98: fcontext -> fclass | ( fclass1 , ... , fclassn ) (n>=0) fclass -> qtycls atype1 ... atypen (n>=1) topdecl -> data [fcontext =>] simpletype = constrs [deriving] | newtype [fcontext =>] simpletype = newconstr [deriving] | class [fcontext =>] tycls tyvar [where cdecls] | instance [fcontext =>] qtycls inst [where idecls] gendecl -> vars :: [fcontext =>] type for the single-argument case. (Note that I wrote type in my proposal in the OP, but it should of course be atype.) ** FlexibleInstances: Enables the use of arguments other than type constructors (possibly applied to tyvars) in instances *heads* (orthogonal to whether there can be one or more arguments, and what the context may look like). Formally it means the following syntactic changes to Haskell 98: topdecl -> instance [scontext =>] qtycls inst [where idecls] inst -> atype for the single-parameter standard-context case. (Note again that it should be atype and not type as I wrote in the OP.) ======================================== This of course only touches the syntactic part. It doesn't attempt to track things like 'instance (T a a) => R a b' that would be enabled by FlexibleContexts, nor does it attempt to track things like the Paterson conditions, but the syntax is all I'm interested in at the moment. This is the stance I will use for haskell-src-exts, unless someone protests wildly. If there is any interest, I can also propose these cases as bug reports to GHC. I hesitate to make formal proposals (e.g. for Haskell') regarding these extensions since I'm not sure I have the full story regarding the non-syntactic parts. But if there is a particular interest in that then I might go the extra mile there too. Cheers, /Niklas