Skip to content

Instantly share code, notes, and snippets.

@hodzanassredin
Last active August 29, 2015 14:03
Show Gist options
  • Save hodzanassredin/85536058247906a37471 to your computer and use it in GitHub Desktop.
Save hodzanassredin/85536058247906a37471 to your computer and use it in GitHub Desktop.
heterogenous list in csharp
using System;
using System.Collections.Generic;
namespace Kinded
{
class HList<TLower>
{
public virtual System.Collections.Generic.IEnumerable<TLower> All ()
{
yield break;
}
private HList ()
{
}
public class NilT : HList<TLower>
{
public List<B, NilT> Add<B> (B val)
where B:TLower
{
return new List<B, NilT> (val, this);
}
public A Append<A> (A list)
where A:HList<Object>
{
return list;
}
public override string ToString ()
{
return string.Format ("[NilT]");
}
}
public static NilT Nil ()
{
return new NilT ();
}
public class List<THEAD, TTAIL>:HList<TLower>
where TTAIL:HList<TLower>
where THEAD : TLower
{
public List (THEAD head, TTAIL tail)
{
Head = head;
Tail = tail;
}
public THEAD Head {
get;
set;
}
public TTAIL Tail {
get;
set;
}
public override System.Collections.Generic.IEnumerable<TLower> All ()
{
yield return Head;
foreach (var item in Tail.All()) {
yield return item;
}
}
public List<B, List<THEAD, TTAIL>> Add<B> (B val)
where B:TLower
{
return new List<B, List<THEAD, TTAIL>> (val, this);
}
public List<THEAD, TTAIL> Append (NilT list)
{
return this;
}
public override string ToString ()
{
return string.Format ("[List: Head={0}, Tail={1}]", Head, Tail);
}
}
}
public interface IPribt
{
void Print ();
}
class A : IPribt
{
public void Print ()
{
Console.WriteLine ("A");
}
}
class B : IPribt
{
public void Print ()
{
Console.WriteLine ("B");
}
}
class MainClass
{
public static HList<Object>.List<int,B> AddIntHead<B> (B list)
where B:HList<Object>
{
return new HList<Object>.List<int,B> (1, list);
}
public static HList<IPribt> Generate<T,T2> (int count)
where T: IPribt, new()
where T2:IPribt, new()
{
if (count == 0)
return HList<IPribt>.Nil ();
var lst = Generate<T2,T> (count - 1);
return new HList<IPribt>.List<T,HList<IPribt>> (new T (), lst);
}
public class User : HList<Object>.List<string,
HList<Object>.List<int,HList<Object>.NilT>>
{
public User (String name, int age)
: base (name, HList<Object>.Nil ().Add<int> (age))
{
}
public string Name ()
{
return this.Head;
}
public int Age ()
{
return this.Tail.Head;
}
}
public class NameTrait<TParent> : HList<Object>.List<string,TParent>
where TParent : HList<Object>
{
public NameTrait (string name, TParent parent) : base (name, parent)
{
}
public string AdditionalName ()
{
return this.Head;
}
}
//anonymous types
public static void Main (string[] args)
{
var floatStrNil = HList<Object>.Nil ().Add ("aaa").Add (1.2);
var intFloatStrNil = AddIntHead (floatStrNil);
Console.WriteLine (intFloatStrNil.Head + 1);
Console.WriteLine (intFloatStrNil.Tail.Tail.Head + " ok");
var ab = HList<IPribt>.Nil ().Add (new A ()).Add (new B ());
foreach (var item in ab.All()) {
item.Print ();
}
foreach (var item in Generate<A,B>(10).All()) {
item.Print ();
}
var user = new User ("hodza", 16);
Console.WriteLine ("User:" + user);
var userWithAddress = user.Add ("Karelia");
Console.WriteLine ("User with address:" + userWithAddress);
AddIntHead (user);
var userWithAdditionalName = new NameTrait<User> ("newName", user);
Console.WriteLine (userWithAdditionalName.AdditionalName ());
Console.ReadKey ();
}
}
}
using System;
using System.Collections.Generic;
namespace Kinded
{
class HMap<TKEY, TLower>
{
public virtual System.Collections.Generic.IEnumerable<KeyValuePair<TKeyLower, TLower>> All ()
{
yield break;
}
private HMap ()
{
}
public class NilT : HMap<TKeyLower, TLower>
{
public Map<A, B, NilT> Add<A, B> (A key, B val)
where B:TLower
where A:TKeyLower
{
return new Map<A, B, NilT> (key, val, this);
}
public A Append<A> (A list)
where A:HMap<TKeyLower, TLower>
{
return list;
}
public override string ToString ()
{
return string.Format ("[NilT]");
}
}
public static NilT Nil ()
{
return new NilT ();
}
public class Map<TVALUE, TTAIL>:HMap<TKeyLower, TLower>
where TTAIL:HMap<TKeyLower, TLower>
where TKEY : TKeyLower
where TVALUE : TLower
{
public Map (TKEY key, TVALUE value, TTAIL tail)
{
Key = key;
Value = value;
Tail = tail;
}
public TKEY Key {
get;
set;
}
public TVALUE Value {
get;
set;
}
public TTAIL Tail {
get;
set;
}
public override System.Collections.Generic.IEnumerable<KeyValuePair<TKeyLower, TLower>> All ()
{
yield return new KeyValuePair<TKeyLower, TLower> (Key, Value);
foreach (var item in Tail.All()) {
yield return item;
}
}
public Map<A, B, Map<TKEY, TVALUE, TTAIL>> Add<A, B> (A key, B val)
where B:TLower
where A:TKeyLower
{
return new Map<A, B, Map<TKEY, TVALUE, TTAIL>> (key, val, this);
}
public Map<TKEY, TVALUE, TTAIL> Append (NilT list)
{
return this;
}
public override string ToString ()
{
return string.Format ("Key={0}, Value={1}, {2}", Key, Value, Tail);
}
}
}
class MainClass
{
public static HMap<string,object>.Map<string,string, TMAP> AddName<TMAP> (TMAP lst, string name)
where TMAP : HMap<string,object>
{
return new HMap<string,object>.Map<string,string, TMAP> ("name", name, lst);
}
//anonymous types
public static void Main (string[] args)
{
var test = HMap<String, Object>
.Nil ()
.Add ("string", "aaa")
.Add ("double", 1.2)
.Add ("int", 1);
Console.WriteLine (test.Value + 1);
Console.WriteLine (test.Tail.Tail.Value + " ok");
Console.WriteLine (test);
foreach (var item in test.All()) {
Console.WriteLine (item.Key, item.Value);
}
var namedTest = AddName ("m name", test);
Console.ReadKey ();
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment