problem with collection (container) class

Hi! I'm pretty (not to say very) new to haskell and i've to create a new class named container that includes types that hold other values, more specific, i have "created" this two types: data Abb a b = Branch a b (Abb a b) (Abb a b) | Leaf and data ListAssoc a b = Node a b (ListAssoc a b) | Empty and implemented some common functions (add, search, delete, empty,etc). So when I was asked to create this new class I crashed against a big problem, or at least for me. My first attempt was: class Container c where empty :: c but when I had to implement "add" I tried add :: c -> a -> b -> c although I was almost sure that it wouldn't work, so I realized that I had to give Container not one but three parameters, the container and the types of values that the container saved so I started searching and I found similar cases, but the difference iis that in this cases the class was defined as follows: class Container c e | c->e where empty :: c insert :: c -> e -> c member :: c -> e -> Bool but my particular problem here is that the types I designed hold two values of different type and these holds just one value. Besides I knew nothing about functional dependency used in here and I keep knowing almost nothing about them, but I tried something like this: class Container c a b |c -> a, c -> b where empty :: c add :: c -> a -> c search :: c -> a -> Maybe b del :: c -> a -> c toListPair :: c -> [(a,b)] instance Container Abb a b where empty = Leaf add Leaf x y = Branch x y Leaf Leaf add arb@(Branch ni nd ri rd) x y |x == ni = arb |x > ni = Branch ni nd ri (add rd x y) |otherwise = Branch ni nd (add ri x y) rd search Leaf x = Nothing search (Branch ni nd ri rd) x |x == ni = Just nd |x > ni = search rd x |x < ni = search ri x but when I try to load it in WinHugs I get the following error message: - Instance is more general than a dependency allows *** Instance : Container Abb a b *** For class : Container a b c *** Under dependency : a -> b and as I have stated above my knowledge about dependencies is almost null, not to say null, so I don´t even have an idea where the error is. A suggestion that I've received was to change the type of Abb for data Abb (a,b) = Branch a b (Abb (a,b)) (Abb (a,b)) | Leaf and declare container class with just two parameters like I found in all pages I visited. I have not tried this yet, as I still have hope that what I intend to do is possible. Well if you have any suggestions I'd appreciate you send it to me and sorry for bothering you and my english, but i'm "spanish-speaker".

Am Donnerstag, 7. Februar 2008 08:58 schrieb Leandro Demarco Vedelago:
but when I try to load it in WinHugs I get the following error message:
- Instance is more general than a dependency allows *** Instance : Container Abb a b *** For class : Container a b c *** Under dependency : a -> b
and as I have stated above my knowledge about dependencies is almost null, not to say null, so I don´t even have an idea where the error is.
Maybe ghci's error message is more helpful: dafis@linux:~/Documents/haskell/move> ghci Leandro GHCi, version 6.8.2: http://www.haskell.org/ghc/ :? for help Loading package base ... linking ... done. [1 of 1] Compiling Leandro ( Leandro.hs, interpreted ) Leandro.hs:16:19: `Abb' is not applied to enough type arguments Expected kind `*', but `Abb' has kind `* -> * -> *' In the instance declaration for `Container Abb a b' Failed, modules loaded: none. There are a couple of other things, mainly that you have the wrong type for 'add' and you need an Ord constraint for 'search'. This works: {-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE FunctionalDependencies #-} {- # LANGUAGE FlexibleInstances # -} module Leandro where data Abb a b = Branch a b (Abb a b) (Abb a b) | Leaf data ListAssoc a b = Node a b (ListAssoc a b) | Empty class Container c a b |c -> a, c -> b where empty :: c add :: c -> a -> b -> c search :: c -> a -> Maybe b del :: c -> a -> c toListPair :: c -> [(a,b)] instance (Ord a) => Container (Abb a b) a b where empty = Leaf add Leaf x y = Branch x y Leaf Leaf add arb@(Branch ni nd ri rd) x y |x == ni = arb |x > ni = Branch ni nd ri (add rd x y) |otherwise = Branch ni nd (add ri x y) rd search Leaf x = Nothing search (Branch ni nd ri rd) x |x == ni = Just nd |x > ni = search rd x |x < ni = search ri x Note: The FlexibleInstances Language pragma is required by GHC 6.8.1 and 6.8.2, but not by GHC 6.6.1 or hugs, I think that's a bug in 6.8.*
A suggestion that I've received was to change the type of Abb for
data Abb (a,b) = Branch a b (Abb (a,b)) (Abb (a,b)) | Leaf
and declare container class with just two parameters like I found in all pages I visited. I have not tried this yet, as I still have hope that what I intend to do is possible.
Well if you have any suggestions I'd appreciate you send it to me and sorry for bothering you and my english, but i'm "spanish-speaker".
Cheers, Daniel

Daniel Fischer wrote:
{-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE FunctionalDependencies #-} {- # LANGUAGE FlexibleInstances # -} module Leandro where
data Abb a b = Branch a b (Abb a b) (Abb a b) | Leaf
data ListAssoc a b = Node a b (ListAssoc a b) | Empty
class Container c a b |c -> a, c -> b where [...]
instance (Ord a) => Container (Abb a b) a b where [...]
Note: The FlexibleInstances Language pragma is required by GHC 6.8.1 and 6.8.2, but not by GHC 6.6.1 or hugs, I think that's a bug in 6.8.*
If it's a bug then it is probably in 6.6.1 too, it just gets hidden by the fact that in 6.6.1 the -fglasgow-exts extensions cannot be activated separately. If you enable one of them, you get them all. Cheers Ben

Am Freitag, 8. Februar 2008 22:14 schrieb Ben Franksen:
If it's a bug then it is probably in 6.6.1 too, it just gets hidden by the fact that in 6.6.1 the -fglasgow-exts extensions cannot be activated separately. If you enable one of them, you get them all.
Thanks for the info, didn't know that. The problem was the error message, which didn't mention that each type variable may appear only once in an instance head, which I had temporarily forgotten. Then the message Leandro.hs:32:0: Illegal instance declaration for `Container (Abb a b) a b' (All instance types must be of the form (T a1 ... an) where a1 ... an are distinct type *variables* Use -XFlexibleInstances if you want to disable this.) In the instance declaration for `Container (Abb a b) a b' looks rather confusing :)
Cheers Ben
Cheers, Daniel

Good point. Happily I improved the error message a couple of weeks ago, so it'll be better in the next release Simon | -----Original Message----- | From: haskell-cafe-bounces@haskell.org [mailto:haskell-cafe-bounces@haskell.org] On Behalf Of Daniel Fischer | Sent: 08 February 2008 22:24 | To: Ben Franksen; haskell-cafe@haskell.org | Subject: Re: [Haskell-cafe] Re: problem with collection (container) class | | Am Freitag, 8. Februar 2008 22:14 schrieb Ben Franksen: | > If it's a bug then it is probably in 6.6.1 too, it just gets hidden by the | > fact that in 6.6.1 the -fglasgow-exts extensions cannot be activated | > separately. If you enable one of them, you get them all. | > | Thanks for the info, didn't know that. | | The problem was the error message, which didn't mention that each type | variable may appear only once in an instance head, which I had temporarily | forgotten. Then the message | | Leandro.hs:32:0: | Illegal instance declaration for `Container (Abb a b) a b' | (All instance types must be of the form (T a1 ... an) | where a1 ... an are distinct type *variables* | Use -XFlexibleInstances if you want to disable this.) | In the instance declaration for `Container (Abb a b) a b' | | looks rather confusing :) | | > Cheers | > Ben | > | Cheers, | Daniel | _______________________________________________ | Haskell-Cafe mailing list | Haskell-Cafe@haskell.org | http://www.haskell.org/mailman/listinfo/haskell-cafe
participants (4)
-
Ben Franksen
-
Daniel Fischer
-
Leandro Demarco Vedelago
-
Simon Peyton-Jones