I&#39;m trying to do some fusion in ghc, and I&#39;d greatly appreciate help with the code below (which is simplified from fusion on linear maps).&nbsp; I&#39;ve tried every variation I can think of, and always something prevents the fusion.<br>
<br>Help, please!&nbsp; Thanks, - Conal<br><br><br><div style="margin-left: 40px;"><span style="font-family: courier new,monospace;">{-# OPTIONS_GHC -O2 -Wall -fglasgow-exts -ddump-simpl -ddump-simpl-stats #-}</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">-- {-# OPTIONS_GHC -ddump-simpl-iterations #-}</span><br style="font-family: courier new,monospace;"><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">module F where</span><br style="font-family: courier new,monospace;">
<br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">-- | Domain of a linear map.</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">class AsInt a where</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">&nbsp; toInt&nbsp;&nbsp; :: a -&gt; Int</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">&nbsp; fromInt :: Int -&gt; a</span><br style="font-family: courier new,monospace;">
<br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">{-# RULES</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">&quot;toInt/fromInt&quot;&nbsp;&nbsp; forall m. toInt (fromInt m) = m</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">&nbsp;#-}</span><br style="font-family: courier new,monospace;"><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">{-# INLINE onInt #-}</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">onInt :: AsInt a =&gt; (Int -&gt; Int) -&gt; (a -&gt; a)</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">onInt f = fromInt . f . toInt</span><br style="font-family: courier new,monospace;">
<br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">test :: AsInt a =&gt; (Int -&gt; Int) -&gt; (Int -&gt; Int) -&gt; (a -&gt; a)</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">test h g = onInt h . onInt g<br><br>-- The desired result:<br>-- <br>--&nbsp;&nbsp; test h g<br>--&nbsp;&nbsp;&nbsp;&nbsp; == onInt h . onInt g<br>--&nbsp;&nbsp;&nbsp;&nbsp; == (fromInt . h . toInt) . (fromInt . g . toInt)<br>
--&nbsp;&nbsp;&nbsp;&nbsp; == \ a -&gt; (fromInt . h . toInt) ((fromInt . g . toInt) a)<br>--&nbsp;&nbsp;&nbsp;&nbsp; == \ a -&gt; (fromInt . h . toInt) (fromInt (g (toInt a)))<br>--&nbsp;&nbsp;&nbsp;&nbsp; == \ a -&gt; fromInt (h (toInt (fromInt (g (toInt a)))))<br>--&nbsp;&nbsp;&nbsp;&nbsp; == \ a -&gt; fromInt (h (g (toInt a)))<br>
</span><br></div><br>