Last active
December 11, 2015 18:58
-
-
Save darth10/4645170 to your computer and use it in GitHub Desktop.
Asinine LazyList in C#
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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