Hello,
<div><br></div><div>I want to use the RULES pragma and cannot get my rules to fire. Here is a simplified example of what I&#39;m trying.</div><div><br></div><div>I define my own version of foldMap for lists:</div><div><div>
<br></div><div>    fold :: Monoid m =&gt; (a -&gt; m) -&gt; [a] -&gt; m</div><div>    fold f = foldr mappend mempty . map f</div><div>    -- alternative, trying to avoid interference with foldr/build fusion</div><div>    -- fold _ []     = mempty</div>
<div>    -- fold f (x:xs) = f x `mappend` fold f xs</div><div>    {-# NOINLINE fold #-}</div></div><div><br></div><div>I try using a NOINLINE pragma to make the firing of my rules (which involve fold) more robust. But they don&#39;t fire with or without NOINLINE. Also the uncommented version does not make a difference.</div>
<div><br></div><div>I also define a function that creates a singleton list:</div><div><br></div><div><div>    single :: a -&gt; [a]</div><div>    single x = [x]</div></div><div>    {-# NOINLINE single #-}</div><div><br></div>
<div>Now I want to replace calls of `fold f . g single` (or eta-expanded versions of this) by `g f` using the following rules:</div><div><br></div><div><div>{-# RULES</div><div>  &quot;monoid fusion pointfree&quot;</div><div>
    forall f (g :: forall m . Monoid m =&gt; (a -&gt; m) -&gt; b -&gt; m) .</div><div>      fold f . g single = g f;</div><div><br></div><div>  &quot;monoid fusion pointed, general&quot;</div><div>    forall f (g :: forall m . Monoid m =&gt; (a -&gt; m) -&gt; b -&gt; m) b .</div>
<div>      fold f (g single b) = g f b;</div><div><br></div><div>  &quot;monoid fusion pointed, for lists&quot;</div><div>    forall f (g :: forall m . Monoid m =&gt; (a -&gt; m) -&gt; [a] -&gt; m) xs .</div><div>      fold f (g single xs) = g f xs;</div>
<div>  #-}</div></div><div><br></div><div>The variations of type signatures (including no signatures at all) for the pattern variables that I tried did not change anything for the better.</div><div><br></div><div>I wrote the third rule only because the second gives a warning that I don&#39;t quite understand:</div>
<div><br></div><div><div>    Warning: Forall&#39;d type variable b is not bound in RULE lhs</div><div>               fold @ m @ a $dMonoid f (g @ [a] $dMonoid (single @ a) b)</div></div><div><div><br></div><div>I try out the rules using the following function that takes the role of `g` in the rules:</div>
<div><br></div><div>    idGen :: Monoid m =&gt; (a -&gt; m) -&gt; [a] -&gt; m</div><div>    idGen _ []     = mempty</div><div>    idGen f (x:xs) = f x `mappend` idGen f xs</div><div>    {-# NOINLINE idGen #-}</div><div><br>
</div><div>Again, I use NOINLINE just in case that would help the rules fire. Here is a main function where the rules should fire:</div><div><br></div><div>    main :: IO ()</div><div>    main =</div><div>      do print ((fold id . idGen single) [[()]])</div>
<div>         print (fold id (idGen single [[()]]))</div></div><div><br></div><div>But they don&#39;t.</div><div><br></div><div>Why don&#39;t the rules fire, what can I change such that they do, and what to get rid of the warning for the second rule (which I think is the one I should use)?</div>
<div><br></div><div>Best regards,</div><div>Sebastian</div><div><br></div><div>Here is the output of -ddump-simple-stats (once with -fenable-rewrite-rules only and once with -O):</div><div><div><br></div><div># ghc --version</div>
<div>The Glorious Glasgow Haskell Compilation System, version 7.0.1</div></div><div><br></div><div><div># ghc -fenable-rewrite-rules -fforce-recomp -ddump-simpl-stats --make rules</div><div>[1 of 1] Compiling Main             ( rules.hs, rules.o )</div>
<div><br></div><div>==================== Grand total simplifier statistics ====================</div><div>Total ticks:     0</div><div><br></div><div>1 SimplifierDone</div><div>    1</div></div><div><br></div><div><div># ghc -O -fforce-recomp -ddump-simpl-stats --make rules</div>
<div>[1 of 1] Compiling Main             ( rules.hs, rules.o )</div><div><br></div><div>==================== FloatOut stats: ====================</div><div>0 Lets floated to top level; 0 Lets floated elsewhere; from 4 Lambda groups</div>
<div><br></div><div><br></div><div><br></div><div>==================== FloatOut stats: ====================</div><div>10 Lets floated to top level; 1 Lets floated elsewhere; from 5 Lambda groups</div><div><br></div><div><br>
</div><div><br></div><div>==================== Grand total simplifier statistics ====================</div><div>Total ticks:     144</div><div><br></div><div>34 PreInlineUnconditionally</div><div>    1 eta_Xp5</div><div>    1 g_amr</div>
<div>    1 eta_amx</div><div>    1 k_amJ</div><div>    1 z_amK</div><div>    1 f_amQ</div><div>    1 g_amR</div><div>    1 x_amS</div><div>    1 k_an9</div><div>    1 z_ana</div><div>    1 g_anb</div><div>    1 f_anf</div>
<div>    1 xs_ang</div><div>    1 eta_aoA</div><div>    2 $dShow_aKW</div><div>    2 x_aKX</div><div>    1 ys_aVd</div><div>    1 c_dmm</div><div>    1 n_dmn</div><div>    1 a_snX</div><div>    1 a_so1</div><div>    1 lvl_sod</div>
<div>    1 lvl_soe</div><div>    1 lvl_sof</div><div>    1 lvl_sog</div><div>    1 lvl_soh</div><div>    1 lvl_soi</div><div>    1 lvl_soj</div><div>    1 a_son</div><div>    1 a_sop</div><div>    1 a_sV0</div><div>    1 a_sV2</div>
<div>17 PostInlineUnconditionally</div><div>    1 k_amv</div><div>    1 f_amQ</div><div>    1 g_amR</div><div>    1 c_ani</div><div>    1 n_anj</div><div>    1 m_anI</div><div>    1 k_anJ</div><div>    2 $dShow_aoy</div><div>
    2 x_aoz</div><div>    1 c_aVa</div><div>    1 f_aVb</div><div>    1 x_aVc</div><div>    1 a_snV</div><div>    1 a_snZ</div><div>    1 lvl_sVA</div><div>15 UnfoldingDone</div><div>    1 GHC.Base.build</div><div>    1 GHC.Base.foldr</div>
<div>    2 System.IO.print</div><div>    1 GHC.TopHandler.runMainIO</div><div>    2 GHC.Base..</div><div>    1 GHC.Base.mapFB</div><div>    1 GHC.Base.$fMonadIO_$c&gt;&gt;</div><div>    2 Main.main</div><div>    2 System.IO.print1</div>
<div>    2 GHC.Show.$fShow[]_$cshow</div><div>8 RuleFired</div><div>    1 Class op &gt;&gt;</div><div>    2 Class op show</div><div>    2 Class op showList</div><div>    1 fold/build</div><div>    1 foldr/nil</div><div>    1 map</div>
<div>8 LetFloatFromLet</div><div>    8</div><div>62 BetaReduction</div><div>    1 eta_Xp5</div><div>    1 a_amq</div><div>    1 g_amr</div><div>    1 a_amt</div><div>    1 b_amu</div><div>    1 k_amv</div><div>    1 z_amw</div>
<div>    1 eta_amx</div><div>    1 b_amH</div><div>    1 a_amI</div><div>    1 k_amJ</div><div>    1 z_amK</div><div>    2 b_amN</div><div>    2 c_amO</div><div>    2 a_amP</div><div>    2 f_amQ</div><div>    2 g_amR</div>
<div>    1 x_amS</div><div>    1 a_an7</div><div>    1 b_an8</div><div>    1 k_an9</div><div>    1 z_ana</div><div>    1 g_anb</div><div>    1 a_and</div><div>    1 a1_ane</div><div>    1 f_anf</div><div>    1 xs_ang</div>
<div>    1 b_anh</div><div>    1 c_ani</div><div>    1 n_anj</div><div>    1 a_anG</div><div>    1 b_anH</div><div>    1 m_anI</div><div>    1 k_anJ</div><div>    2 a_aox</div><div>    2 $dShow_aoy</div><div>    2 x_aoz</div>
<div>    1 eta_aoA</div><div>    2 a_aKV</div><div>    2 $dShow_aKW</div><div>    2 x_aKX</div><div>    1 elt_aV7</div><div>    1 lst_aV8</div><div>    1 a_aV9</div><div>    1 c_aVa</div><div>    1 f_aVb</div><div>    1 x_aVc</div>
<div>    1 ys_aVd</div><div>    1 a_dml</div><div>    1 c_dmm</div><div>    1 n_dmn</div><div>13 SimplifierDone</div><div>    13</div></div><div><br></div>