
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. -Brent