Skip to content

Instantly share code, notes, and snippets.

@hodzanassredin
Created June 26, 2014 21:25
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save hodzanassredin/4de8fc7bbfbf4bb7dfa7 to your computer and use it in GitHub Desktop.
Save hodzanassredin/4de8fc7bbfbf4bb7dfa7 to your computer and use it in GitHub Desktop.
Higher-Rank Polymorphism in c#
using System;
using System.Collections.Generic;
namespace HK
{
public class Forall{}
public interface IGeneric<T, TCONTAINER>
{
}
public static class GenericExts
{
public static TM UpCast<T, TM, TMB> (this IGeneric<T, TMB> m)
where TM : TMB, IGeneric<T, TMB>
{
return (TM)m;//safe for single inheritance
}
}
interface IFn<A,B>{
CB Apply<T,CA,CB> (CA a)
where CA : A, IGeneric<T,A>
where CB : B, IGeneric<T,B>;
}
public class Id{
public sealed class IdGeneric<T> : Id, IGeneric<T, Id>
{
public IdGeneric (T val)
{
Value = val;
}
public T Value {
get;
set;
}
}
}
public class List{
public sealed class ListGeneric<T> : List, IGeneric<T, List>
{
public ListGeneric ()
{
}
public void Add(T val){
}
}
}
class MainClass
{
class ToList : IFn<Id,List>
{
#region IFn implementation
public CB Apply<T, CA, CB> (CA a) where CA : Id, IGeneric<T, Id> where CB : List, IGeneric<T, List>
{
var val = a.UpCast<T,Id.IdGeneric<T>,Id> ().Value;
var res = new List.ListGeneric<T>();
res.Add (val);
return res.UpCast<T,CB,List>();
}
#endregion
}
//Higher-Rank Polymorphism in c#
//def apply[B](f: (A => List[A]) forAll { A }, b: B, s: String): (List[B], List[String]) =(f(b), f(s))
public static Tuple<BI, BS> ApplY<A,B, AI, AS, BI, BS> (IFn<A,B> f, AI i, AS str)
where AI : A, IGeneric<int, A>
where AS : A, IGeneric<string, A>
where BI : B, IGeneric<int, B>
where BS : B, IGeneric<string, B>
{
var a = f.Apply<int,AI,BI> (i);
var b = f.Apply<string,AS,BS> (str);
return Tuple.Create (a, b);
}
public static void Main (string[] args)
{
ApplY<Id, List, Id.IdGeneric<int>, Id.IdGeneric<string>, List.ListGeneric<int>, List.ListGeneric<string>>(new ToList(), new Id.IdGeneric<int>(1), new Id.IdGeneric<string>("sss"));
Console.WriteLine ("Hello World!");
Console.ReadKey ();
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment