Skip to content

Instantly share code, notes, and snippets.

@dimitris-papadimitriou-chr
Created June 25, 2019 19:30
Show Gist options
  • Save dimitris-papadimitriou-chr/275f80434140f450a37e188a77d533f9 to your computer and use it in GitHub Desktop.
Save dimitris-papadimitriou-chr/275f80434140f450a37e188a77d533f9 to your computer and use it in GitHub Desktop.
Free Monad in C#
public interface IFunctor<T>
{
IFunctor<T1> Map<T1>(Func<T, T1> map);
}
public class Id<T> : IFunctor<T>
{
private T source;
public Id(T v) => source = v;
public IFunctor<T1> Map<T1>(Func<T, T1> map) => new Id<T1>(map(source));
}
public abstract class Free<T>
{
public abstract Free<T1> Map<T1>(Func<T, T1> map);
public abstract Free<T1> Bind<T1>(Func<T, Free<T1>> bind);
}
public class Pure<T> : Free<T>
{
private T source;
public Pure(T v) => source = v;
public override Free<T1> Map<T1>(Func<T, T1> map) => new Pure<T1>(map(source));
public override Free<T1> Bind<T1>(Func<T, Free<T1>> bind) => bind(source);
}
public class Roll<T, F> : Free<T> where F : IFunctor<Free<T>>
{
private F source;
public Roll(F v) => source = v;
public override Free<T1> Map<T1>(Func<T, T1> f) => new Roll<T1, IFunctor<Free<T1>>>(source.Map(x => x.Map(f)));
public override Free<T1> Bind<T1>(Func<T, Free<T1>> f) => new Roll<T1, IFunctor<Free<T1>>>(source.Map(x => x.Bind(f)));
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment