Έχουν δημοσιευτεί
Κυριακή, 13 Σεπτεμβρίου 2009 10:44 μμ
από το μέλος
PALLADIN
Ο Bart de smet συνεχίζει την πολύ καλή σειρά από posts, και αυτή την φορα μας παρουσιάζει ένα cache Enumerable, μαζί με έναν "let" binder.
Φυσικά λείπει το αδελφάκι "letrec", όπου έμεινε ως άσκηση για τον αναγνώστη.
(η αφορμή που έψαχνα για να ξυπνήσει Ο old schemer μέσα μου)
delegate Func<A, R> Recursive<A, R>(Recursive<A, R> r);
static Func<A, R> Y<A, R>(Func<Func<A, R>, Func<A, R>> f)
{
Recursive<A, R> rec = r => a => f(r(r))(a);
return rec(rec);
}
public static IEnumerable<U> Let<T, U>(this IEnumerable<T> source, Func<IEnumerable<T>, IEnumerable<U>> function)
{
using (var mem = new MemoizeEnumerable<T>(source))
{
foreach (var item in function(mem))
yield return item;
}
}
public static IEnumerable<U> LetRec<T, U>(this IEnumerable<T> source, Func<Func<IEnumerable<T>, IEnumerable<U>>, Func<IEnumerable<T>, IEnumerable<U>>> function)
{
Func<Func<IEnumerable<T>, IEnumerable<U>>, Func<IEnumerable<T>, IEnumerable<U>>> letWrap =
f => x => Let(x, function(f));
return Y(letWrap)(source);
}