Trac #2110

Simon Peyton-Jones simonpj at
Mon Sep 16 10:56:01 UTC 2013


I'm not convinced about your solution.  It seems a bit of a hack. Moreover, the very same issue arises for ordinary type classes, so I'd prefer to solve it for all of them at once.  Finally, the very existence of Coercible is going to eliminate most of these (map Age) calls anyhow.  Using them, and then a RULE to optimise them away, seems perverse.

Do paste this email into the ticket... I'm on a plane.

Suppose f :: (a->a->a) -> [a] -> [a], and fGr :: [a] -> [a]

Now consider

{-# RULE "foo"   f (>) = fGr    #-}

which would translate to the following CoreRule:

          forall a, d:Ord a.
                    f a ((>) a d) = fGr

If we saw a call to f in a polymorphic context, the rule would fire
          g :: Ord a => [a] -> blah
          g xs = ...(f (>) xs)....

But if we specialise g with a type signature, suddenly the rule wouldn't fire:
          g :: [Int] -> blah
          g xs = ...(f (>) xs)....

Why?  Because the (>) would simplify to grInt, which isn't what the RULE looks for.  This is similar to your use of coerce simplifying too eagerly.

The right solution seems to be to give the RULE a chance to fire before inlining/simplifying calls to (>).   One way to do that is to prevent the ClassOp rule (defined in MkId) from firing in the "gentle" phase, which is always the first simplifier phase.  I'm not sure of the consequences of that; see Note [RULEs enabled in SimplGently] in CoreMonad.

Moreover currently BuiltinRules don't have an Activation to say when they should be active.  This would be easy to change though.

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <>

More information about the ghc-devs mailing list