Skip to content

Instantly share code, notes, and snippets.

@darth10
Last active December 11, 2015 18:58
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save darth10/4645170 to your computer and use it in GitHub Desktop.
Save darth10/4645170 to your computer and use it in GitHub Desktop.
Asinine LazyList in C#
class FibonacciPair<T> : Tuple<T, T>
{
public T A { get; private set; }
public T B { get; private set; }
public FibonacciPair(T a, T b) : base(a, b)
{
A = a;
B = b;
}
}
class FibonacciSequence
{
readonly static FibonacciPair<double> _first =
new FibonacciPair<double>(0, 1);
static FibonacciPair<double> Next(FibonacciPair<double> curr)
{
return new FibonacciPair<double>(curr.B, curr.A + curr.B);
}
public static IEnumerable<double> Sequence
{
get
{
return LazyList<FibonacciPair<double>>
.Iterate(n => Next(n), _first)
.Select(pair => pair.A);
}
}
public static void Main(string[] args)
{
var fibonacciSeq = FibonacciSequence.Sequence;
var fibo50 = fibonacciSeq.Take(50).Last();
var fibo1000 = fibonacciSeq.Take(1000).Last();
var fibo2000 = fibonacciSeq.Take(2000).Last(); // becomes infinity
}
}
class LazyList<T> : IEnumerable<T>, IEnumerable
{
T _first;
Lazy<LazyList<T>> _rest;
public T First { get { return _first; } }
public LazyList<T> Rest { get { return _rest.Value; } }
public LazyList(T first, Lazy<LazyList<T>> rest)
{
_first = first;
_rest = rest;
}
public static LazyList<T> Iterate<T>(Func<T, T> f, T x)
{
return new LazyList<T>(x, new Lazy<LazyList<T>>(delegate
{
return Iterate(f, f(x));
}));
}
public static LazyList<T> Repeat<T>(T x)
{
return new LazyList<T>(x, new Lazy<LazyList<T>>(delegate
{
return Repeat(x);
}));
}
#region IEnumerable[T] implementation
IEnumerator<T> IEnumerable<T>.GetEnumerator()
{
return new LazyListEnumerator<T>(this);
}
#endregion
#region IEnumerable implementation
IEnumerator IEnumerable.GetEnumerator()
{
return new LazyListEnumerator<T>(this);
}
#endregion
}
class LazyListEnumerator<T> : IEnumerator<T>, IEnumerator
{
LazyList<T> _next, _curr = null;
public LazyListEnumerator(LazyList<T> parent)
{
_next = parent;
}
T Current
{
get
{
if(_curr == null)
throw new InvalidOperationException();
return _curr.First;
}
}
#region IEnumerator[T] implementation
T IEnumerator<T>.Current { get { return Current; } }
#endregion
#region IEnumerator implementation
bool IEnumerator.MoveNext()
{
_curr = _next;
_next = _next.Rest;
return _curr != null;
}
void IEnumerator.Reset()
{
throw new NotSupportedException("Cannot reset a LazyList");
}
object IEnumerator.Current { get { return Current; } }
#endregion
#region IDisposable implementation
void System.IDisposable.Dispose()
{
}
#endregion
}
class NaturalSeq
{
readonly static int _first = 0;
static int Next(int i)
{
var j = i + 1;
Console.WriteLine(String.Format("Next({0}) -> {1}", i, j));
return j;
}
public static IEnumerable<int> Sequence
{
get
{
return LazyList<int>
.Iterate(i => Next(i), _first);
}
}
public static void Main(string[] args)
{
var naturalSeq = NaturalSeq.Sequence;
foreach(int n in naturalSeq.Take(20))
{
Console.WriteLine(n);
}
var nat21 = naturalSeq.Take(21).ToArray(); // only '21' is realized
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment