Created
June 27, 2012 07:55
-
-
Save ssboisen/3002299 to your computer and use it in GitHub Desktop.
Unfold in C# .
This file contains 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
public sealed class Option<T> : IEquatable<Option<T>> | |
{ | |
private readonly T m_Value; | |
private static readonly Option<T> g_None = new Option<T>(); | |
private Option() { } | |
private Option(T value) | |
{ | |
m_Value = value; | |
} | |
public override bool Equals(object obj) | |
{ | |
if (obj is Option<T>) | |
return Equals((Option<T>)obj); | |
return false; | |
} | |
public bool Equals(Option<T> other) | |
{ | |
if (IsNone) | |
return other.IsNone; | |
return EqualityComparer<T>.Default.Equals(m_Value, other.m_Value); | |
} | |
public override int GetHashCode() | |
{ | |
if (IsNone) | |
return 0; | |
return EqualityComparer<T>.Default.GetHashCode(m_Value); | |
} | |
public bool IsNone | |
{ | |
get { return this == g_None; } | |
} | |
public bool IsSome | |
{ | |
get { return !IsNone; } | |
} | |
public T Value | |
{ | |
get | |
{ | |
if (IsSome) | |
return m_Value; | |
throw new InvalidOperationException(); | |
} | |
} | |
public static Option<T> None | |
{ | |
get { return g_None; } | |
} | |
public static Option<T> Some(T value) | |
{ | |
return new Option<T>(value); | |
} | |
} | |
public static class Option | |
{ | |
public static Option<T> Some<T>(T value) | |
{ | |
return Option<T>.Some(value); | |
} | |
} | |
public static class Extensions | |
{ | |
public static IEnumerable<TResult> Unfold<T, TResult>(this T start, Func<T, Option<Tuple<TResult, T>>> generator) | |
{ | |
var next = start; | |
while (true) | |
{ | |
var res = generator(next); | |
if (res.IsNone) | |
yield break; | |
yield return res.Value.Item1; | |
next = res.Value.Item2; | |
} | |
} | |
} | |
//Example | |
static void Main() | |
{ | |
var sequence = 0.Unfold(i => | |
{ | |
if (i < 10) | |
return Option.Some(Tuple.Create(i + 1, i + 1)); | |
return Option<Tuple<int, int>>.None; | |
}).ToList(); | |
var sequence = 0.Unfold(i => Option.Some(Tuple.Create(i + 1, i + 1))).Take(10).ToList(); | |
Console.ReadLine(); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment