unfold
(unfold p f g seed tail-gen) == (if (p seed) (tail-gen seed) (cons (f seed) (unfold p f g (g seed))))
public static IEnumerable<U> Unfold<T, U>(Predicate<T> p, Func<T, U> f, Func<T, T> g, T seed) { if (p(seed)) return Enumerable.Empty<U>(); return Cons(f(seed), Unfold(p, f, g, g(seed))); } public static IEnumerable<T> Cons<T>(T car, IEnumerable<T> cdr) { yield return car; foreach (T element in cdr) yield return element; }