Created
October 13, 2015 21:12
-
-
Save noblethrasher/154ffc5afa7effd402b1 to your computer and use it in GitHub Desktop.
An example of using type class style, ad-hoc polymorphism
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
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