
Hi all, I am trying to get a GHC rewrite rule that specialises a function according to the type of the argument of the function. Does anybody know whether it is possible to do that not with a concrete type but rather a type class? Consider the following example:
class A a where toInt :: a -> Int {-# NOINLINE toInt #-}
class B a where toInt' :: a -> Int
The idea is to use the method of type class A unless the type is also an instance of type class B. Let's say that Bool is an instance of both A and B:
instance A Bool where toInt True = 1 toInt False = 0
instance B Bool where toInt' True = 0 toInt' False = 1
Now we add a rule that says that if the argument to "toInt" happens to be an instance of type class B as well, use the method "toInt'" instead:
{-# RULES "toInt" forall (x :: B a => a) . toInt x = toInt' x #-}
Unfortunately, this does not work (neither with GHC 6.12 or GHC 7.0). Expression "toInt True" gets evaluated to "1". If the rewrite rule is written with a concrete type it works as expected:
{-# RULES "toInt" forall (x :: Bool) . toInt x = toInt' x #-}
Now "toInt True" is evaluated to "0". Am I doing something wrong or is it not possible for GHC to dispatch a rule according to type class constraints? Thanks, Patrick