Rewrite rules and let abstraction in GHC : <p>I have a rewrite rule that looks like this:</p>

<pre><code>{-# RULES
"modify/fusedModify" forall f g key book. modify key f (modify key g book) = fusedModify key f g book
  #-}
</code></pre>

<p>Which fires in the following function:</p>

<pre><code>pb :: PersonB
pb = ...

fusionB' :: PersonB
fusionB' =
  let l x = (modify #name ('c':) (modify #name ('a':) x))
  in l pb
</code></pre>

<p>However, without let (and presumably let-abstraction?) it does not fire:</p>

<pre><code>fusionB :: PersonB
fusionB = modify #name ('c':) (modify #name ('a':) pb)
</code></pre>

<p>If it went the <em>other</em> way - that is, if the let-abstracted version didn't cause a firing, but <code>fusionB</code> did - I think I'd understand. It could be that in the specific case, <code>fusedModify</code> has the right type signature, but in the general (more polymorphic) case, it doesn't. But why in the world am I seeing this? </p>

<p>For what it's worth, the definition of <code>fusedModify</code> is <a href="https://github.com/turingjump/bookkeeper/blob/fusion/bookkeeper/src/Bookkeeper/Internal.hs#L127" rel="noreferrer">here</a>, and the file with <code>fusionB</code> and <code>fusionB'</code> is <a href="https://github.com/turingjump/bookkeeper/blob/fusion/bookkeeper/bench/Main.hs" rel="noreferrer">here</a>. I've tried <code>unsafeCoercing</code> type equalities to get both signatures to match up (in reality, though GHC doesn't realize it, they do always match), but somehow that doesn't help either. </p>

<p><em>EDIT</em>: I should perhaps mention that I'm using GHC 8.0.1.</p>
