Allowing duplicate instances in GHC 6.4
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
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
>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)
Now you datasources just need to return the type "TJust v" on success
and TNothing on failure.
More information about the Glasgow-haskell-users