Define combination of type classes?

What is the easiest way to name a combination of type classes, i.e., to abbreviate the fact that a certain type is an instance of several classes simultaneously? I have a vague sense that this is do-able, but that I am messing up by trying to use an empty class body as below. So in the code below, I try to use FooBar to abbreviate the conjunction of Foo and Bar. But while f (which uses a FooBar constraint) has a valid definition, it can't be used. On the other hand, g (which uses the long-winded constraint), is both a valid defined and useable. (In a real example, imagine that FooBar names a conjunction of a half dozen things, so that the g-like form really is onerous, whereas the f-like form would be sweet and tidy :) .) -- Fritz ------------------- class Foo a where foo :: a -> Int class Bar a where bar :: a -> a class (Foo a, Bar a) => FooBar a f :: FooBar a => a -> Int f a = foo (bar a) g :: (Foo a, Bar a) => a -> Int g a = foo (bar a) instance Foo Char where foo = ord instance Bar Char where bar = id

On 24/03/2006, at 12:45 PM, Fritz Ruehr wrote:
What is the easiest way to name a combination of type classes, i.e., to abbreviate the fact that a certain type is an instance of several classes simultaneously? I have a vague sense that this is do-able, but that I am messing up by trying to use an empty class body as below.
So in the code below, I try to use FooBar to abbreviate the conjunction of Foo and Bar. But while f (which uses a FooBar constraint) has a valid definition, it can't be used. On the other hand, g (which uses the long-winded constraint), is both a valid defined and useable.
(In a real example, imagine that FooBar names a conjunction of a half dozen things, so that the g-like form really is onerous, whereas the f-like form would be sweet and tidy :) .)
Hi Fritz! You only need to do a couple of things to get this working. Add an instance declaration: instance (Foo a, Bar a) => FooBar a But for this to work you need to allow undecidable instances (and - fglasgow-exts). To have this type class synonym trick work you need both the class and instance declaration: class (Foo a, Bar a) => FooBar a instance (Foo a, Bar a) => FooBar a The first ensures that members of class FooBar will inherit the methods of classes Foo and Bar. The second ensures that if there is a Foo and a Bar instance then there will be a FooBar instance. You were lacking this in your code hence the error message:
f 'a'
No instance for (FooBar Char) arising from use of `f' at <interactive>:1:0 Probable fix: add an instance declaration for (FooBar Char) In the definition of `it': it = f 'a' This is a neat trick. I've also used it to reduce onerous contexts. Sean

Another option is to just add the instance:
instance FooBar Char
instead of
instance (Foo a, Bar a) => FooBar a
Now you don't need any extensions, the disadvantage is that you have to add an instance for each type... There has also been an proposal for type class synonyms: http://repetae.net/john/recent/out/classalias.html Maybe you like it, Gerrit Sean Seefried wrote:
On 24/03/2006, at 12:45 PM, Fritz Ruehr wrote:
What is the easiest way to name a combination of type classes, i.e., to abbreviate the fact that a certain type is an instance of several classes simultaneously? I have a vague sense that this is do-able, but that I am messing up by trying to use an empty class body as below.
So in the code below, I try to use FooBar to abbreviate the conjunction of Foo and Bar. But while f (which uses a FooBar constraint) has a valid definition, it can't be used. On the other hand, g (which uses the long-winded constraint), is both a valid defined and useable.
(In a real example, imagine that FooBar names a conjunction of a half dozen things, so that the g-like form really is onerous, whereas the f-like form would be sweet and tidy :) .)
Hi Fritz!
You only need to do a couple of things to get this working. Add an instance declaration:
instance (Foo a, Bar a) => FooBar a
But for this to work you need to allow undecidable instances (and - fglasgow-exts).
To have this type class synonym trick work you need both the class and instance declaration:
class (Foo a, Bar a) => FooBar a instance (Foo a, Bar a) => FooBar a
The first ensures that members of class FooBar will inherit the methods of classes Foo and Bar. The second ensures that if there is a Foo and a Bar instance then there will be a FooBar instance. You were lacking this in your code hence the error message:
f 'a'
No instance for (FooBar Char) arising from use of `f' at <interactive>:1:0 Probable fix: add an instance declaration for (FooBar Char) In the definition of `it': it = f 'a'
This is a neat trick. I've also used it to reduce onerous contexts.
Sean _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
participants (3)
-
Fritz Ruehr
-
Gerrit van den Geest
-
Sean Seefried