Allowing duplicate instances in GHC 6.4

Keean Schupke k.schupke at imperial.ac.uk
Fri Mar 25 11:18:55 EST 2005


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 ...
> 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.
>
>  

Further to this to get the exact behaviour you want, if a datasource can 
return the result using a type lifted maybe on a lookup failure then:

 >class Datasource s k v | s k -> v ...
 >data JoinedDS l r = JoinedDS l r
 >instance (Datasource l k v1,
 >    Datasource r k v2,
 >    JoinDS v1 v2 v) => Datasource (JoinedDS l r) k v
 >
 >class Fail
 >data This_should_never_happen
 >
 >data TNothing = TNothing
 >data TJust a = TJust a
 >
 >class JoinDS l r t | l r -> t
 >instance JoinDS TNothing TNothing TNothing
 >instance JoinDS TNothing (TJust v) (TJust v)
 >instance JoinDS (TJust u) TNothing (TJust u)
 >instance Fail This_should_never_happen => JoinDS (TJust u) (TJust v) 
TNothing

Now you datasources just need to return the type "TJust v" on success 
and TNothing on failure.

    Keean.



More information about the Glasgow-haskell-users mailing list