В C# как мне memoize функцию с двумя аргументами?Два аргумента Memoization
Должен ли я делать карри перед записью?
Wes Dyer wrote the Memoization code Я обычно использую, но теперь мне нужно два аргумента
В C# как мне memoize функцию с двумя аргументами?Два аргумента Memoization
Должен ли я делать карри перед записью?
Wes Dyer wrote the Memoization code Я обычно использую, но теперь мне нужно два аргумента
Вы просто создаете перегруженную версию метода Memoize, который имеет три общих типа и принимает функцию с двумя параметрами и двумя аргументами. Он по-прежнему возвращает функцию без параметров:
public static Func<R> Memoize<A1,A2,R>(this Func<A1,A2,R> f, A1 a1, A2 a2)
{
R value = default(R);
bool hasValue = false;
return() =>
{
if (!hasValue)
{
hasValue = true;
value = f(a1,a2);
}
return value;
};
}
Edit:
Кроме того, вы должны сделать пользовательский IEqualityComparer для KeyValuePair, который содержит два аргумента для метода Memoize, чтобы иметь возможность вернуть функцию с двумя параметрами :
public static Func<A1,A2,R> Memoize<A1,A2,R>(this Func<A1,A2,R> f, IEqualityComparer<KeyValuePair<A1,A2>> comparer)
{
var map = new Dictionary<KeyValuePair<A1,A2>,R>(comparer);
return (a1,a2) =>
{
R value;
KeyValuePair<A1,A2> key = new KeyValuePair<A1,A2>(a1,a2);
if (map.TryGetValue(key, out value)) {
return value;
}
value = f(a1,a2);
map.Add(key, value);
return value;
};
}
Вы должны быть в состоянии memoize пару. Две функции arg вызывают одну функцию arg, которую вы memoize.
У Уэс есть еще одна почта, где он дает a two (or more) argument version of Memoize. Он не требует специального сравнения.
С новыми версиями .NET вы можете упростить код Принятого решения, немного с помощью кортежей
public static Func<TParam1, TParam2, TReturn> Memoize<TParam1, TParam2, TReturn>(Func<TParam1, TParam2, TReturn> func)
{
var map = new Dictionary<Tuple<TParam1, TParam2>, TReturn>();
return (param1, param2) =>
{
var key = Tuple.Create(param1, param2);
TReturn result;
if (!map.TryGetValue(key, out result))
{
result = func(param1, param2);
map.Add(key, result);
}
return result;
};
}
Я также сделал некоторую работу над запоминанием в C#. Мои результаты аналогичны, но используют ключ словаря, полученный из конкатенации хеш-кодов входных объектов. Шаблон может быть расширен до такого количества входов, как позволяет Func <>.
Se больше здесь: http://bit.ly/t6iNJP
Да, этот код намного лучше Wes. Вы и Гуффа верны, но Гуффа приложил больше усилий, поэтому я награждаю его. Спасибо хоть! – CVertex