
On 04/06/2011 22:49, Brent Yorgey wrote:
On Fri, Jun 03, 2011 at 05:13:43PM +0300, Guy wrote:
On 03/06/2011 16:55, Daniel Schoepe wrote:
On Fri, 03 Jun 2011 16:04:05 +0300, Guy
wrote: I have some code resembling
class Foo f where foo :: a -> f a
data Bar f a = Foo f => Bar {bar :: f a}
instance Foo (Bar f) where foo a = Bar $ foo a
GHC insists on Foo f => in the instance declaration. However, the definition of Bar guarantees that this will always be the case. Why do I have to state this explicitly?
The constraints in the data type declaration only affect the constructors. It's a known issue, unfortunately there doesn't seem to be a way around it.
It seems to work for simpler examples. For example, this is OK
data X x = Show x => X x
s :: X x -> String s (X x) = show x
I don't have to add a Show x => type constraint to s.
In this case, you are *destructing* an X value, and when you do, the Show constraint on x becomes available, since the X constructor is always paired with a Show constraint.
In your original example, you are *constructing* a Bar value. You have stated that the Bar constructor must be accompanied by a Foo constraint, but there is no such constraint in sight!
So the difference is between *destructing* a value (when the associated constraint becomes available) and *constructing* one (when the required constraint must be provided).
I don't know if I've explained that well. As others have mentioned, the ability to specify constraints on constructors in this way is probably going to be removed from the language anyway.
So in my original example, why isn't "instance Foo (Bar f)" destructing Bar - and making the constraint available?