Created
December 25, 2020 08:21
-
-
Save mjgoeke/1c5a5d28f0580946be7942e7a899c3e3 to your computer and use it in GitHub Desktop.
C# memoize higher order functions by using tuples
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Concurrent; | |
namespace ns | |
{ | |
//even though this looks like it only takes functions with one input | |
// by using C# tuple types, one can have any number of inputs (or outputs) | |
// see example below | |
public class Memoized<T, TResult> | |
{ | |
public Memoized(Func<T, TResult> func) => _func = func; | |
private readonly Func<T, TResult> _func; | |
private readonly ConcurrentDictionary<T,TResult> _cache = new ConcurrentDictionary<T, TResult>(); | |
public TResult Get(T input) => _cache.GetOrAdd(input, _func); | |
} | |
public static class MemoizedExtensions | |
{ | |
public static Func<T, TResult> Memoize<T, TResult>(this Func<T, TResult> func) => new Memoized<T, TResult>(func).Get; | |
} | |
class Program | |
{ | |
static void Main() | |
{ | |
var fun = new Func<(double x, double y , double z), (double x, double y, double z)>(inverse).Memoize(); | |
Console.WriteLine("fun: " + fun((1.1, 2.1, 3.1))); // will WriteLine in 'inverse' function the first time | |
Console.WriteLine("fun: " + fun((1.1, 2.1, 3.1))); // will directly return result after called once | |
Console.WriteLine("fun: " + fun((1.1, 2.1, 3.1))); | |
} | |
static (double x, double y, double z) inverse((double x, double y, double z) vec) | |
{ | |
var (x, y, z) = vec; | |
Console.WriteLine(string.Format("{0} called ({1}, {2}, {3})", nameof(inverse), x, y, z)); | |
return (-x, -y, -z); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment