Kevin
Sorry it's taken me a long time to look at this.
Two things are going on here.
First thing
module KevinB where
data Arr ix el = Arr Int [(ix,el)] deriving Show
replaceMany :: [(ix,el)] - Arr ix el - Arr ix el
replaceMany = error "In Replace Many"
{-# RULES
"rule1" forall f,l,a. replaceMany (map f l) a = replaceManyMap f l a
#-}
replaceManyMap :: (v - (ix,el)) - [(ix,el)] - Arr ix el - Arr ix el
replaceManyMap = error "In Replace Many Map"
arr s l = let a = Arr s [] in
replaceMany l a
If you compile this, replaceMany will be inlined in arr's defn,
which means that anyone importing KevinB won't see the version
of arr that has replaceMany in it. So
module KevinA where
import KevinB
arr2 s l = arr s (map (\(i,e)-(i+2,e)) l)
will not fire the rule.
Solution: add an INLINE pragma to 'arr'. This has the
effect of *preventing* inlining in arr's RHS, and causing
'arr' to be inlined at every call site.
This is an annoying gotcha when using RULES, but I don't see an
easy fix.
Second thing
~~
But, as you discovered, it still doesn't work. Reason: GHC spots
that 'arr' always returns bottom, and therefore declines to put
an inlining in the interface file at all. Optimising functions that
are guaranteed to diverege isn't much use. If you make your
replace* things do something useful I think you'll find it will work.
Simon
-Original Message-
From: Kevin Atkinson
Sent: Thursday, July 01, 1999 6:13 PM
To: Simon Peyton-Jones
Cc: 'GHC users'
Subject: Re: Rule question.
Simon Peyton-Jones wrote:
Hmm. Your example relies on inlining 'arr' at its call site.
My guess is that you aren't using -O. In that case, there's no
cross-module inlining, so 'arr' doesn't get inlined.
Is that it?
No:
[kevina@kevins-linux Rules]$ make clean
rm -f *.o *.hi
[kevina@kevins-linux Rules]$ make
ghc -c T2.hs -fglasgow-exts -O
ghc: module version changed to 1; reason: no old .hi file
ghc -c Main.hs -fglasgow-exts -O
ghc: module version changed to 1; reason: no old .hi file
rm -f main
ghc -o main -fglasgow-exts -O Main.o T2.o
[kevina@kevins-linux Rules]$ ./main
Fail: In Replace Many
An INLINE arr did not help either.
--
Kevin Atkinson
[EMAIL PROTECTED]
http://metalab.unc.edu/kevina/