<p>Hi<br>
This method is what I&#39;m looking for. it&#39;s a nice general solution, but it doesn&#39;t solve my problem here.<br>
I&#39;m using ghc 7.0.3, I tried to cache p2num and montgKeys in the way you showed. It seems that ghc doesn&#39;t memorize p2num and reject to compile new montgKeys.<br>
I think caching values with dynamic types is complicated in ghc&#39;s runtime environment. Anyone knows the details?</p>
<div class="gmail_quote">On Nov 7, 2011 7:07 AM, &quot;wren ng thornton&quot; &lt;<a href="mailto:wren@freegeek.org">wren@freegeek.org</a>&gt; wrote:<br type="attribution"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
On 11/6/11 10:51 AM, Bin Jin wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Yes, but I think it&#39;s not a funtion since the function didn&#39;t use the<br>
parameter. So maybe there is a way to make memorizing possible.<br>
</blockquote>
<br>
In general, if the argument is not used then<br>
<br>
    \x -&gt; E<br>
<br>
is equal to<br>
<br>
    let e = E in \x -&gt; e<br>
<br>
Which we can make strict by adding a bang-pattern or a seq<br>
<br>
    let !e = E in \x -&gt; e<br>
  ==<br>
    let e = E in e `seq` \x -&gt; e<br>
<br>
The strictness isn&#39;t always necessary, but it helps to ensure that GHC doesn&#39;t get rid of the let-binding which would take us back to the original (\x -&gt; E). Now, if we use this as the definition of the function, it&#39;ll ensure that the computation of E is done as a CAF and hence is memoized (since laziness is call-by-name + memoization).<br>

<br>
<br>
This trick can be generalized to any function of which parts of it are constant in some subset of parameters. That is, if we have<br>
<br>
    \x y z -&gt; E (F (G H x) y) z<br>
<br>
then this can be converted into<br>
<br>
    let !h = H in<br>
    \x -&gt;<br>
    let !g = G h x in<br>
    \y -&gt;<br>
    let !f = F g y in<br>
    \z -&gt;<br>
    E f z<br>
<br>
Now, whenever we want to use this function we pass in as many arguments as we are holding fixed, and force the resulting function in order to memoize the initial computations. For example, if the above function is called foo, then we could use it like:<br>

<br>
    forM xs $ \x -&gt; do<br>
        let !foo_x = foo x<br>
        forM ys $ \y -&gt; do<br>
            let !foo_x_y = foo_x y<br>
            forM zs $ \z -&gt; do<br>
                let !foo_x_y_z = foo_x_y z<br>
                ...<br>
<br>
In this example we&#39;re performing loop invariant code motion, but doing so dynamically in order to maintain a separation between the definition of foo and its use.<br>
<br>
-- <br>
Live well,<br>
~wren<br>
<br>
______________________________<u></u>_________________<br>
Haskell-Cafe mailing list<br>
<a href="mailto:Haskell-Cafe@haskell.org" target="_blank">Haskell-Cafe@haskell.org</a><br>
<a href="http://www.haskell.org/mailman/listinfo/haskell-cafe" target="_blank">http://www.haskell.org/<u></u>mailman/listinfo/haskell-cafe</a><br>
</blockquote></div>