[Haskell-cafe] rewrite rules to specialize function according to type class?

Patrick Bahr pa-ba at arcor.de
Mon Feb 14 22:43:53 CET 2011

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?


More information about the Haskell-Cafe mailing list