
Hello! I got a multi-parameter type class:
class Foo a b | a -> b where foo_method1 :: ... foo_method2 :: ... ...
And some particular cases are important on their own, like the one where 'a' and 'b' are the same, I call elements with this property, Bar. So I defined: class Foo a a => Bar a where This is nice, now I can replace (F a a) for (Bar a) in the context of many functions. Less typing and it's more readable. Still, I have to define instances as:
instance Foo A A where foo_method1 = bla1 foo_method2 = bla2
instance Bar A where
I'd like to achieve something better than this. I was looking for something like "class synonyms". So if I declared an instance Foo A A, I automagicaly had Bar A, because they'd be the same. Or even better, I could declare
instance Bar A where foo_method1 = bla1 foo_method2 = bla2
Is anything like this possible at all? Thanks, J.A.

Maybe I should have included a more interesting example in the previous mail. So I had this class:
class Foo a b | a -> b where foo_method1 :: ... foo_method2 :: ... ...
Besides the case where 'a' is the same as 'b', there is also another interesting case. That is when you have both, Foo A B and Foo B A. This is a known property (named DoubleFoo), so I'd like to type contexts as,
DoubleFoo a b =>
instead of,
(Foo a b, Foo b a) =>
so I tried:
class (Foo a b, Foo b a) => DoubleFoo a b where
This works fine if I'm going to define functions which need both instances of Foo. Something like:
testDouble :: DoubleFoo a b => a -> b -> c testDouble a b = foo_method1 a b ... foo_method1 b a
but it doesn't help me with:
testDouble2 :: DoubleFoo a b => a -> b -> c testDouble2 a b = foo_method1 a b ... testDouble2 b a
now I need DoubleFoo b a as well. Seems to me like there is no way of saying:
Foo a b , Foo b a <=> DoubleFoo a b
right? J.A.

Jorge,
Besides the case where 'a' is the same as 'b', there is also another interesting case. That is when you have both, Foo A B and Foo B A. This is a known property (named DoubleFoo) [...]
Again, with -fallow-undecidable-instances: \begin{code} class (Foo a b, Foo b a) => DoubleFoo a b instance (Foo a b, Foo b a) => DoubleFoo a b \end{code} HTH, Stefan

Jorge,
Besides the case where 'a' is the same as 'b', there is also another interesting case. That is when you have both, Foo A B and Foo B A. This is a known property (named DoubleFoo) [...]
Again, with -fallow-undecidable-instances:
\begin{code} class (Foo a b, Foo b a) => DoubleFoo a b instance (Foo a b, Foo b a) => DoubleFoo a b \end{code}
Ah! Got it. Thanks Stefan, J.A.

Jorge,
I'd like to achieve something better than this. I was looking for something like "class synonyms". So if I declared an instance Foo A A, I automagicaly had Bar A, because they'd be the same.
Using -fallow-undecidable-instances (in GHC) you could do: \begin{code} class Foo a b | a -> b where foo_method1 :: ... foo_method2 :: ... ... class (Foo a a) => Bar a where instance (Foo a a) => Bar a where -- replaces all your other Bar instances instance Foo Integer Integer where foo_method1 = ... foo_method2 = ... \end{code} HTH, Stefan
participants (2)
-
Jorge Adriano Aires
-
Stefan Holdermans