Skip to content

Instantly share code, notes, and snippets.

@hodzanassredin
Created September 30, 2011 13:23
Show Gist options
  • Save hodzanassredin/1253727 to your computer and use it in GitHub Desktop.
Save hodzanassredin/1253727 to your computer and use it in GitHub Desktop.
Trying to workaround missed higher-kinded type parameters in c#
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace FunctorTest
{
public interface SingleParamPolymorph<T> { }
public interface TwoParamsPolymorph<T, U> { }
/// <summary>
/// REalization of \Haskell's Functor:
/// class Functor f where
/// fmap :: (a -> b) -> f a -> f b
/// C# version DOESNT COMPILE
/// interface IFunctor<T> {
/// T<B> FMap<A, B>(Func<A, B> f, T<A> a);
/// }
/// class ListFunctor<T> : IFunctor<List<>> {
/// List<B> FMap<A, B>(Func<A, B> f, List<A> a) {
/// ...
/// }
///}
/// </summary>
/// <typeparam name="ACONT"></typeparam>
/// <typeparam name="BCONT"></typeparam>
/// <typeparam name="A"></typeparam>
/// <typeparam name="B"></typeparam>
public interface IFunctor<ACONT, BCONT, A, B>
where ACONT : SingleParamPolymorph<A>
where BCONT : SingleParamPolymorph<B>
{
BCONT FMap(Func<A, B> f, ACONT a);
}
public class Container<T> : SingleParamPolymorph<T>
{
public Container(T val)
{
Value = val;
}
public T Value { get; set; }
}
public class MyList<T> : List<T>, SingleParamPolymorph<T>
{
public MyList()
{
}
public MyList(List<T> from)
{
this.AddRange(from);
}
}
public class ContainerFunctor<T> : IFunctor<Container<T>, Container<T>, T, T>
{
public Container<T> FMap(Func<T, T> f, Container<T> a)
{
return new Container<T>(f(a.Value));
}
}
public class ListFunctor<A, B> : IFunctor<MyList<A>, MyList<B>, A, B>
{
public MyList<B> FMap(Func<A, B> f, MyList<A> a)
{
return new MyList<B>(a.Select(x => f(x)).ToList());
}
}
class Program
{
static void Main(string[] args)
{
var lst = new MyList<String>();
lst.Add("aa");
lst.Add("bbb");
Func<String, int> f = x => x.Length;
var res = new ListFunctor<String, int>().FMap(f, lst);
Console.WriteLine(res[0]);
Console.WriteLine(res[1]);
Console.ReadLine();
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment