Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>This largely follows <a href="http://www.haskell.org/haskellwiki/Memoization" rel="noreferrer">http://www.haskell.org/haskellwiki/Memoization</a>.</p> <p>You want a function of type (a -> b). If it doesn't call itself, then you can just write a simple wrapper that caches the return values. The best way to store this mapping depends on what properties of a you can exploit. Ordering is pretty much a minimum. With integers you can construct an infinite lazy list or tree holding the values.</p> <pre><code>type Cacher a b = (a -&gt; b) -&gt; a -&gt; b positive_list_cacher :: Cacher Int b positive_list_cacher f n = (map f [0..]) !! n </code></pre> <p>or</p> <pre><code>integer_list_cacher :: Cacher Int b integer_list_cacher f n = (map f (interleave [0..] [-1, -2, ..]) !! index n where index n | n &lt; 0 = 2*abs(n) - 1 index n | n &gt;= 0 = 2 * n </code></pre> <p>So, suppose it is recursive. Then you need it to call not itself, but the memoized version, so you pass that in instead:</p> <pre><code>f_with_memo :: (a -&gt; b) -&gt; a -&gt; b f_with_memo memoed base = base_answer f_with_memo memoed arg = calc (memoed (simpler arg)) </code></pre> <p>The memoized version is, of course, what we're trying to define.</p> <p>But we can start by creating a function that caches its inputs:</p> <p>We could construct one level by passing in a function that creates a structure that caches values. Except we need to create the version of f that <em>already has</em> the cached function passed in.</p> <p>Thanks to laziness, this is no problem:</p> <pre><code>memoize cacher f = cached where cached = cacher (f cached) </code></pre> <p>then all we need is to use it: </p> <pre><code>exposed_f = memoize cacher_for_f f </code></pre> <p>The article gives hints as to how to use a type class selecting on the input to the function to do the above, rather than choosing an explicit caching function. This can be really nice -- rather than explicitly constructing a cache for each combination of input types, we can implicitly combine caches for types a and b into a cache for a function taking a and b.</p> <p>One final caveat: using this lazy technique means the cache never shrinks, it only grows. If you instead use the IO monad, you can manage this, but doing it wisely depends on usage patterns.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload