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.

_______________________________________________
Glasgow-haskell-users mailing list
Glasgow-haskell-users@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users

Reply via email to