GHC bug,or Hugs feature?

Simon Peyton-Jones simonpj@microsoft.com
Wed, 28 Aug 2002 12:20:32 +0100


There are two things going on.

1.  Hugs deals with mutual recursion in a more sophisticated
way than GHC.  Mark T is absolutely right, and the THIH paper explains.

2.  Furthermore,GHC implements the H98 requirement that the context of
all functions in a mutually recursive groups must be the same.  So
	f :: Eq a =3D> ...
	g :: Ord a =3D> ...
is illegal if f and g are mutually recursive.


Both these things arise from the way GHC translates mutually recursive
overloaded defns.  Consider

	f :: Ord a =3D> a -> a -> a
	f x y =3D ...(x=3D=3Dy)...(x>y)...(f y x)...

GHC translates it thus:

	f ord_dict =3D let gr =3D select_gr ord_dict
			 eq_dict =3D select_eq ord_dict
			eq =3D select_eq eq_dict

		       	fm x y =3D ...(eq x y)...(ord x y) ...(fm y x)...
		       in
			fm

Note that all the dictionary selection (and sometimes construction)
is done outside the loop, implemented by 'fm'.

Matters get more complicated when there is mutual recursion; suffice it
it say
that in order to pull the dictionary manipuation outside the loop, all
the contexts
must be the same.

Arguably, H98 and GHC are wrong, and the restrictions should be lifted.
GHC usually errs on the side of lifting restrictions (with
-fglasgow-exts) but on=20
this occasion the benefit seemed slight, while it turns out that the
cost of
changing the way let/where is dealt with is not inconsiderable.  So I've
let
sleeping dogs lie.

I think it's a corner case that seldom matters.  Counter examples to
this
claim would be interesting.  At least I hope this explains what's
happening.

Simon



| -----Original Message-----
| From: Mark Tullsen [mailto:mtullsen@cse.ogi.edu]=20
| Sent: 09 August 2002 20:31
| To: haskell@haskell.org
| Cc: Arthur Baars
| Subject: Re: GHC bug,or Hugs feature?
|=20
|=20
| I believe the incompatibilities are explained thus:
|=20
|   In section 4.5.1 of the Haskell Report it only states that
|    "A dependency analysis transformation is first performed=20
| to increase
|     polymorphism"
|=20
|   But hugs appears to be using a more refined version of the=20
| dependency
|   analysis as explained in section 11.6.3 of Mark Jones' paper Typing
|   Haskell in Haskell.  Read that section.
|=20
| - Mark
|=20
|=20
| Arthur Baars wrote:
| > In Mark Jones' paper Typing Haskell in Haskell, I found the=20
| following=20
| > example(in the section on binding-groups):
| >=20
| > f   :: Eq a =3D> a -> Bool
| > f x =3D x=3D=3Dx || g True
| > g y =3D y<=3Dy || f True
| >=20
| > According to the paper the inferred type of g should be: =20
| g::Ord a =3D>=20
| > a -> Bool
| >=20
| > Hugs infers this type but GHC infers the following=20
| *ambiguous* type:=20
| > *Main> :i g
| > -- g is a variable, defined at Test.hs:25
| > g :: forall a. (Eq a) =3D> Bool -> Bool
| >=20
| > When adding an explicit type signature for g, Hugs happily=20
| accepts the=20
| > code, but GHC gives the following error:
| >=20
| > f   :: Eq a =3D> a -> Bool
| > f x =3D x=3D=3Dx || g True
| > g   :: Ord a =3D> a -> Bool
| > g y =3D y<=3Dy || f True
| >=20
| > Test.hs:24:
| >     Couldn't match `{Ord a}' against `{Eq a1}'
| >     When matching the contexts of the signatures for
| >       g :: forall a. (Ord a) =3D> a -> Bool
| >       f :: forall a. (Eq a) =3D> a -> Bool
| >     The signature contexts in a mutually recursive group=20
| should all be=20
| > identical
| >     When generalising the type(s) for g, f
| > Failed, modules loaded: none.
| >=20
| > I think the problems are caused by differences in the binding group=20
| > analysis in Hugs and GHC.
| >=20
| > Malcolm, could you check what NHC says about the examples above?
| >=20
| > Cheers,
| >  Arthur
| >=20
| > _______________________________________________
| > Haskell mailing list
| > Haskell@haskell.org http://www.haskell.org/mailman/listinfo/haskell
| >=20
|=20
|=20
| _______________________________________________
| Haskell mailing list
| Haskell@haskell.org http://www.haskell.org/mailman/listinfo/haskell
|=20