incompatible signatur syntax within instance definition

Fergus Henderson fjh at cs.mu.OZ.AU
Wed Dec 10 17:23:50 EST 2003


On 09-Dec-2003, Christian Maeder <maeder at tzi.de> wrote:
> Fergus Henderson wrote:
> >Or were you referring to the fact that variables which are already
> >constrained can't be constrained again?  IMHO that is a feature too.
> >It doesn't make sense to constrain a variable at any point other than
> >the point where that variable is introduced.
> 
> Indeed, repeating a constraint should be no error (at most a warning) 
> and be it only to let "ghc -fglasgow-exts" except [accept] more programs
> than ghc does without extensions.

Allowing repeated constraints would not be sufficient for that.  The fact
that the two type variables in the case originally posted happened to have
the same constraint is somewhat coincidental; in Haskell 98, the inner
variable might have absolutely no relationship with the outer variable.

Consider the following example:

	data MyType a = MkMyType a
	class Foo a where
		foo :: a -> Int

	instance Foo (MyType a) where
		foo _ = bar (42::Int) where
			bar :: a -> a
			bar x = x

This is legal in Haskell 98, because the `a' in the inner declaration is
implicitly universally quantified.  But if the scope of the outer type
variable `a' extends over the inner type declaration, then the inner `a'
will not be locally universally quantified, and the call to `bar' will
be a type error, because the `a' in the head of the instance declaration
will in general be different than `Int'.

	data MyType a = MkMyType a
	class Foo a where
		foo :: a -> Int

	instance Foo (MyType a) where
		foo _ = bar (42::Int) where
			bar :: a -> a
			bar x = x

Indeed, the scoping of type variables can affect the meaning
of programs, not just their legality.  Consider the following
variation:

	data MyType a = MkMyType a
	class Foo a where
		foo :: a -> String

	instance Num a => Foo (MyType a) where
		foo _ = bar 42 where
			bar :: Num a => a -> String
			bar x = show x

If the scope over the outer `a' does not extend over the inner `a',
then the implicit `fromInteger 42' will be resolved by the defaulting
rules to `fromInteger 42 :: Int'.  But if the outer `a' extends over
the inner `a', then it will be `fromInteger 42 :: a'.  These could
have different semantics, e.g. if called in the following context.

	data MyNum = MyNum
	instance Eq MyNum where
		_ == _ = True
	instance Num MyNum where
		fromInteger _ = MyNum
	instance Show MyNum where
		show MyNum = "MyNum"

	main = print (foo (MkMyType MyNum))

With Haskell 98, this program will print "42".  With ghc and your
proposed change to allow multiple qualifications, it would print "MyNum".
With ghc as it stands, you get an error, because the variable `a' is
qualified multiple times.

So, to summarize, this particular ghc extension is not a pure extension.
It can change the legality or even the semantics of Haskell 98 code.
Allowing repeated constraints won't change that.
Given that allowing repeated constraints isn't sufficient to solve
that problem, I don't think it is a good idea to allow them.

P.S. I note that ghc 5.02.2 enables this extension always, regardless
of the setting of -fglasgow-exts.  That seems like a bug to me.

-- 
Fergus Henderson <fjh at cs.mu.oz.au>  |  "I have always known that the pursuit
The University of Melbourne         |  of excellence is a lethal habit"
WWW: <http://www.cs.mu.oz.au/~fjh>  |     -- the last words of T. S. Garp.


More information about the Glasgow-haskell-users mailing list