Skip to content

Instantly share code, notes, and snippets.

@loosechainsaw
Created July 15, 2014 06:07
Show Gist options
  • Save loosechainsaw/845af3f55b59f0442f7a to your computer and use it in GitHub Desktop.
Save loosechainsaw/845af3f55b59f0442f7a to your computer and use it in GitHub Desktop.
csharp monadic styles
public interface IMaybe<T>
{
IMaybe<U> Fmap<U>(Func<T,U> apply);
IMaybe<U> Bind<U>(Func<T,IMaybe<U>> apply);
IMaybe<V> Bind<U, V>(Func<T, IMaybe<U>> func, Func< U, V> map);
void Foreach(Action<T> action);
U Fold<T,U> (Func<T,U> some, Func<U> none);
}
public static class MaybeExtensions
{
public static IMaybe<T> Just<T>(this T value)
{
return new Just<T>(value);
}
public static IMaybe<T> ToMaybe<T>(this T value)
{
if (value == null)
return new None<T>();
return new Just<T>(value);
}
public static IMaybe<V> SelectMany<T, U, V>(this IMaybe<T> m, Func<T, IMaybe<U>> func, Func<T,U,V> select)
{
return m.Bind(a => func(a).Bind(b => select(a, b).ToMaybe()));
}
}
public class Just<T> : IMaybe<T>
{
public Just(T value)
{
this.value = value;
}
public IMaybe<U> Fmap<U>(Func<T,U> apply)
{
return new Just<U>(apply(value));
}
public IMaybe<U> Bind<U>(Func<T,IMaybe<U>> apply)
{
return apply(value);
}
public IMaybe<V> Bind<U, V>(Func<T, IMaybe<U>> func, Func< U, V> map)
{
return func(value).Fmap(map);
}
public void Foreach(Action<T> action)
{
action(value);
}
public U Fold<T1, U>(Func<T1, U> some, Func<U> none)
{
return some(value);
}
private readonly T value;
}
public class None<T> : IMaybe<T>
{
public IMaybe<U> Fmap<U>(Func<T,U> apply)
{
return new None<U>();
}
public IMaybe<U> Bind<U>(Func<T,IMaybe<U>> apply)
{
return new None<U>();
}
public IMaybe<V> Bind<U, V>(Func<T, IMaybe<U>> func, Func<U, V> map)
{
return new None<V>();
}
public void Foreach(Action<T> action)
{
}
public U Fold<T1, U>(Func<T1, U> some, Func<U> none)
{
return none();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment