
At Sat, 29 Sep 2012 13:04:59 +0400, MigMit wrote:
Well, it seems that you can't do exactly what you want. So, the simplest way to do this would be not to make Foo a superclass for Bar:
class Bar a where foo :: Foo a b => a -> b -> c
Then you would have to mention Foo everywhere.
Just to clarify, I already worked my way around that problem. I want to know why I can't do it since it seems a useful feature to have. In fact, I was doing something very similar to what you're proposing before, but I think having the additional argument is better in my code, for various reasons. You can check the actual class here: https://github.com/bitonic/language-spelling/blob/c3b11111fa3014983acf41f924..., I've left the old version commented.
If you really need, for some reason, to ensure that every Bar instance has a corresponding Foo instance, you can do some oleging this way:
data Void b = Void data FooEv a where FooEv :: Foo a b => Void b -> FooEv a class Bar a where barFoo :: FooEv a bar :: Foo a b => a -> b -> c
Then, whenever you need Foo methods, you can do pattern-matching:
case barFoo :: FooEv a of FooEv (Void :: Void b) -> …
Now some "b" is in scope, and there is an instance of Foo a b.
Well, I'm sure there are endless ways to get around this, but in cases like this the resulting mess far outweighs the advantages :). -- Francesco * Often in error, never in doubt