Skip to content

Instantly share code, notes, and snippets.

@noblethrasher
Created October 13, 2015 21:12
Show Gist options
  • Save noblethrasher/154ffc5afa7effd402b1 to your computer and use it in GitHub Desktop.
Save noblethrasher/154ffc5afa7effd402b1 to your computer and use it in GitHub Desktop.
An example of using type class style, ad-hoc polymorphism
class Program
{
static void Main(string[] args)
{
var buffy = new Person("Buffy Summers", DateTime.Parse("1/19/1981"));
var xander = new Person("Xander Harris", DateTime.Parse("5/2/1981"));
var willow = new Person("Willow Rosenberg", DateTime.Parse("12/3/1980"));
var oldest = OrderModule<Person>.Max(buffy, xander, willow);
}
}
public static class OrderModule<T>
{
public abstract class Order
{
public T Value { get; }
public Order(T value)
{
this.Value = value;
}
public abstract int Compare(Order other);
public static implicit operator T(Order ord) => ord.Value;
}
public static Order Max(params Order[] xs) => Max(xs as IEnumerable<Order>);
public static Order Max(IEnumerable<Order> xs)
{
Order max = null;
foreach (var x in xs)
{
max = x;
foreach (var y in xs.Skip(1))
if (y.Compare(max) > 0)
max = y;
break;
}
return max;
}
static IEnumerable<Order> QuickSort(IEnumerable<Order> xs)
{
var stack = new Stack<Stack<Order>>(new[] { new Stack<Order>(xs) });
while (stack.Any())
{
var qs = stack.Pop();
var head = from q in qs where q.Compare(qs.Peek()) == 0 select q;
var less = from q in qs where q.Compare(qs.Peek()) < 0 select q;
var more = from q in qs where q.Compare(qs.Peek()) > 0 select q;
if (less.Any())
stack.Push(new Stack<Order>(less));
if (more.Any())
{
stack.Push(new Stack<Order>(head));
stack.Push(new Stack<Order>(more));
}
else
foreach (var q in head)
yield return q;
}
}
}
public sealed class Person
{
public string FullName { get; }
public DateTime Dob { get; }
public Person(string fullname, DateTime dob)
{
FullName = fullname;
Dob = dob;
}
public static implicit operator OrderModule<Person>.Order (Person p) => new BirthOrder(p);
sealed class BirthOrder : OrderModule<Person>.Order
{
public BirthOrder(Person p) : base(p) { }
public override int Compare(OrderModule<Person>.Order that)
{
if (this.Value.Dob < that.Value.Dob)
return -1;
if (this.Value.Dob > that.Value.Dob)
return 1;
return 0;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment