asc-community / HonkSharp

Some wrappers and API and methods for fast and convenient declarative coding in C#
47 stars 4 forks source link

Built-in memoization #23

Open WhiteBlackGoose opened 3 years ago

WhiteBlackGoose commented 3 years ago

With recursion. Example of code:

PoC

using System;
using System.Collections.Generic;
using static Memes;

var fib = Memoize<int, int>((n, fib) => 
    n switch
    {
        <= 1 => 1,
        var m => fib(n - 1) + fib(n - 2)
    });
Console.WriteLine(fib(40));

public static class Memes
{
    public static Func<TIn, TOut> Memoize<TIn, TOut>(Func<TIn, Func<TIn, TOut>, TOut> func)
    {
        var dic = new Dictionary<TIn, TOut>();
        Func<TIn, TOut> rec = null;
        rec = tin =>
        {
            if (dic.TryGetValue(tin, out var res))
                return res;
            res = func(tin, rec);
            dic[tin] = res;
            return res;
        };
        return rec;
    }
}

API

public static Func<TIn, TOut> Memoize<TIn, TOut>(Func<TIn, Func<TIn, TOut>> func);
public static (Func<TIn1, TOut1>, Func<TIn2, TOut2>) Memoize<TIn1, TIn2, TOut1, TOut2>(Func<TIn1, Func<TIn1, TOut1>, Func<TIn2, TOut2>, TOut1> func1, Func<TIn2, Func<TIn1, TOut1>, Func<TIn2, TOut2>, TOut2> func2);
...
WhiteBlackGoose commented 2 years ago

Re-consideration with #25: make

prec : (a * (a -> b) -> b) -> a -> b
mrec : (a * (a -> b) -> b) -> a -> b

Where mrec is a memoizing recursor