[Haskell-cafe] Functional dependencies and incoherent instances

Tobias Bexelius tobias.bexelius at avalanchestudios.se
Wed Oct 8 09:59:57 EDT 2008


Yeah, I realized that.

But heres where I would like the undecidable incoherent instances to kick in, i.e. as long as I haven't got any NumVec instances GHC should be able to choose only one of the Mult instances. Or do I have too much faith in the -fallow-incoherent-instances flag now? :/

I would like to be able to write something like
> instance (Vec a x, -Num (a x)) => Mult (a x) (a x) x where (*.) = dot
where -Num (a x) means that (a x) must not be an instance of Num. Can I express this in some way?

Regards
Tobias

-----Original Message-----
From: Joel Björnson [mailto:joel.bjornson at gmail.com] 
Sent: den 8 oktober 2008 15:50
To: Tobias Bexelius
Cc: haskell-cafe at haskell.org
Subject: Re: [Haskell-cafe] Functional dependencies and incoherent instances

Hi,

On Wed, Oct 8, 2008 at 2:31 PM, Tobias Bexelius <tobias.bexelius at avalanchestudios.se> wrote:
> Hi,
>
> Im trying to overload a multiplication operator for scalars and 
> vectors, but keep running into the error message "Functional 
> dependencies conflict". What I think is going on is that the 
> dependency check doesn't work with incoherent (or overlapping) 
> instances. In the example below, the two instances of Mult are 
> overlapping. What I want is the vector version to be used for vectors 
> and the scalar version used for numbers, even if a vector-type is an 
> instance of the Num-class (I believe -fallow-incoherent-instances 
> would make that kind of choise for me, right?).
>
> Im using the Visual Studio plugin Visual Haskell, and thus GHC version 
> 6.6. Otherwise I think associated types might have worked better for 
> this...
>
>
> {-# OPTIONS_GHC -fglasgow-exts -fallow-undecidable-instances 
> -fallow-incoherent-instances #-}
>
> data V2 a = V2 a a
>
> class Vec v a where
>    dot :: v a -> v a -> a
> instance Num a => Vec V2 a where
>    V2 a1 a2 `dot` V2 b1 b2 = a1*b1+a2*b2
>
> class Mult a b c | a b -> c where
>        (*.) :: a -> b -> c
> instance (Num x) => Mult x x x where (*.) = (*) instance (Vec a x) => 
> Mult (a x) (a x) x where (*.) = dot

According to the definition of Mult the parameter 'c' from above should be uniquely determined by a pair of types 'a' and 'b'. Now, lets say we have a type NumVec that instantiates both the Vec class and the Num as in

instance Num (NumVec a) where
instance Vec NumVec a where

Then according to the instance declaration

instance (Num x) => Mult x x x where ...

(NumVec a)  (NumVec a) (NumVec a) instantiates the class. On the other hand looking at the instance declaration:

instance (Vec a x) => Mult (a x) (a x) x where ...

(NumVec a) (NumVec a)  a , is also an instance why the fun dep (a b ->
c) is violated.

Regards,
Joel


More information about the Haskell-Cafe mailing list