[Haskell-cafe] Getting rid of functional dependencies with type
proxies
Tobias Bexelius
tobias.bexelius at avalanchestudios.se
Thu Nov 13 05:09:44 EST 2008
Hi,
some time ago I asked about a problem I had with functional dependencies
conflicting when using overlapping instances in a code like 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
{-
Functional dependencies conflict between instance declarations:
instance [overlap ok] (Num x) => Mult x x x
instance [overlap ok] (Vec a x) => Mult (a x) (a x) x
-}
The problem here is that the dependency check is occuring too soon.
Removing the dependency would solve the problem, but then you would need
to put type annotations everywhere you use the multiplication operator,
and that's not acceptable.
However, I did found a solution I would like to share with you: Creating
a "type proxy"! I find it strange that such a simple solution to such a
(for me at least) common problem hasn't been documented more.
This is the working code:
{-# 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
class MultProxy a b c where
(*..) :: a -> b -> c
instance MultProxy a b c => Mult a b c where
(*.) = (*..)
instance (Num x) => MultProxy x x x where (*..) = (*)
instance (Vec a x) => MultProxy (a x) (a x) x where (*..) = dot
Thanks to Emil Axelsson that pointed me to
http://haskell.org/haskellwiki/GHC/AdvancedOverlap, where similar
problems where discussed. Again, I haven't found links to this page in
any of the Haskell tutorials I've read so far.
/Tobias
More information about the Haskell-Cafe
mailing list