Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>How about this? First write a one-argument memoizer:</p> <pre><code>static Func&lt;A, R&gt; Memoize&lt;A, R&gt;(this Func&lt;A, R&gt; f) { var d = new Dictionary&lt;A, R&gt;(); return a=&gt; { R r; if (!d.TryGetValue(a, out r)) { r = f(a); d.Add(a, r); } return r; }; } </code></pre> <p>Straightforward. Now write a function tuplifier:</p> <pre><code>static Func&lt;Tuple&lt;A, B&gt;, R&gt; Tuplify&lt;A, B, R&gt;(this Func&lt;A, B, R&gt; f) { return t =&gt; f(t.Item1, t.Item2); } </code></pre> <p>And a detuplifier:</p> <pre><code>static Func&lt;A, B, R&gt; Detuplify&lt;A, B, R&gt;(this Func&lt;Tuple&lt;A, B&gt;, R&gt; f) { return (a, b) =&gt; f(Tuple.Create(a, b)); } </code></pre> <p>and now a two-argument memoizer is easy:</p> <pre><code>static Func&lt;A, B, R&gt; Memoize&lt;A, B, R&gt;(this Func&lt;A, B, R&gt; f) { return f.Tuplify().Memoize().Detuplify(); } </code></pre> <p>To write a three-argument memoizer just keep following this pattern: make a 3-tuplifier, a 3-untuplifier, and a 3-memoizer.</p> <p>Of course, if you don't need them, there's no need to make the tuplifiers nominal methods:</p> <pre><code>static Func&lt;A, B, R&gt; Memoize&lt;A, B, R&gt;(this Func&lt;A, B, R&gt; f) { Func&lt;Tuple&lt;A, B&gt;, R&gt; tuplified = t =&gt; f(t.Item1, t.Item2); Func&lt;Tuple&lt;A, B&gt;, R&gt; memoized = tuplified.Memoize(); return (a, b) =&gt; memoized(Tuple.Create(a, b)); } </code></pre> <p>UPDATE: You ask what to do if there is no tuple type. You could write your own; it's not hard. Or you could use anonymous types:</p> <pre><code>static Func&lt;T, R&gt; CastByExample&lt;T, R&gt;(Func&lt;T, R&gt; f, T t) { return f; } static Func&lt;A, B, R&gt; Memoize&lt;A, B, R&gt;(this Func&lt;A, B, R&gt; f) { var example = new { A=default(A), B=default(B) }; var tuplified = CastByExample(t =&gt; f(t.A, t.B), example); var memoized = tuplified.Memoize(); return (a, b) =&gt; memoized(new {A=a, B=b}); } </code></pre> <p>Slick, eh?</p> <hr> <p>UPDATE: C# 7 now has value tuples built in to the language; use them rather than rolling your own or using anonymous types.</p>
 

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