Skip to content

Instantly share code, notes, and snippets.

@ElectricCoffee
Created December 22, 2013 19:21
Show Gist options
  • Save ElectricCoffee/8087074 to your computer and use it in GitHub Desktop.
Save ElectricCoffee/8087074 to your computer and use it in GitHub Desktop.
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApplication1
{
class ConsList<T> : IEnumerable where T : IComparable<T>
{
private const string EXCEPTION = "Cannot traverse empty list";
private T _head;
private ConsList<T> _tail;
public ConsList(T head, ConsList<T> tail)
{
IsEmpty = false;
Head = head;
Tail = tail;
}
public static ConsList<T> Init(params T[] items)
{
var count = items.Length - 1;
var list = Nil;
for (var i = count; i >= 0; i--)
{
list = list.Prepend(items[i]);
}
return list;
}
public bool IsEmpty { get; protected set; }
public static ConsList<T> Nil
{
get
{
return new ConsList<T>(default(T), null) { IsEmpty = true };
}
}
public T Head
{
get
{
if (!IsEmpty) return _head;
else throw new NullReferenceException("Head of empty list");
}
protected set
{
_head = value;
}
}
public ConsList<T> Tail
{
get
{
if (!IsEmpty) return _tail;
else throw new NullReferenceException("Tail of empty list");
}
protected set
{
_tail = value;
}
}
public ConsList<T> Prepend(T value)
{
return new ConsList<T>(value, this);
}
public ConsList<T> Reverse()
{
var result = Nil;
ForEach(h => result = result.Prepend(h));
return result;
}
public IEnumerator GetEnumerator()
{
var temp = this;
while (temp.IsEmpty == false)
{
yield return temp.Head;
temp = temp.Tail;
}
}
public void ForEach(Action<T> headAction)
{
var temp = this;
while (temp.IsEmpty == false)
{
headAction(temp.Head);
temp = temp.Tail;
}
}
public List<T> ToList()
{
var lst = new List<T>();
ForEach(h => lst.Add(h));
return lst;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment