
Keean Schupke wrote:
Robert van Herk wrote:
Hi all,
I need to use duplicate instances. I read in the documentation on GHC 6.4, that overlapping class instances checks are lazy instead of gready in 6.4. However, my code still gives duplicate instance errors when compiling in GHC 6.4.
Is the duplicate instance check still gready? Is there a way to overwrite that behaviour?
Right now, I have two instance of a class Datasource. Datasource allows the user to read (key,value) pairs.
class Datasource ds k v where ...
Now, I wanted to make a special datasource that combines two datasources, namely
data JoinedDS left right = JoinedDS left right instance (Datasource left k v) => Datasource (JoinedDS left right) k v where ...
instance (Datasource right k v) => Datasource (JoinedDS left right) k v where ...
The idea is that when you combine 2 datasources in one JoinedDS, the user can read both types from the JoinedDS. I do not need to allow to combine 2 different datasources that have the same types of (key,value) pairs, so the duplicate instances will not occur and when they do, this will be by mistake. Hence, the two premisses in the instance declaration will never be fulfilled both at the same time and I do not want a duplicate instance error here.
Is there a solution to this problem?
To resolve overlap the HEAD of the instance must be different... Might I suggest:
-- as value depends on source and key, requires functional dependancy class Datasource s k v | s k -> v ...
Yes, I already had that, forgot to mention it though...
data JoinedDS l r = JoinedDS l r instance (Datasource l k v1,Datasource r k v2) => Datasource (JoinedDS l r) k (v1,v2) ...
Now a joined datasource resturns a pair of values instead of a single value.
Yes, but this is not what I want. I want to be able to give a key that either the left or the right data source would take, and then return the appropriate value. Thus: if I pass it a key that would normally go into l, I want the value l returns me to be returned, and if I pass it the key that would normally go into r, I want to return the value r returns me. The datasource class has a function dsread :: ds -> k -> (ds, v) -- read may have a side effect Thus I want want to do something like: instance (Datasource l k v) => Datasource (JoinedDS l r) k v where dsread (JoinedDS l r) k = let (l, v) = dsread l k in (JoinedDS l r, v) instance (Datasource r k v) => Datasource (JoinedDS l r) k v where dsread (JoinedDS l r) k = let (r, v) = dsread r k in (JoinedDS l r, v) It would be perfectly okay to me when the compiler would complain if the key and value that go into l and r are the same, but for any useful purpose I can think of (e.g. glueing two database couplings together, since I also made a Datasource instance for database access), this will not happen and the duplicate instances should not really occur, since the context of the instances makes sure only 1 will be possible. However, GHC only looks at the RHS (thus: Datasource (JoinedDS l r) k v) and then decides that both instances are the same. So, my question was: how to overcome this. Thanks, Robert