Skip to content

Instantly share code, notes, and snippets.

@matthewphilyaw
Last active December 26, 2015 20:29
Show Gist options
  • Save matthewphilyaw/0d10acf7b675c87cccbe to your computer and use it in GitHub Desktop.
Save matthewphilyaw/0d10acf7b675c87cccbe to your computer and use it in GitHub Desktop.
Maybe monad in C#
using System;
namespace Maybe
{
interface Maybe<T>
{
T Value();
bool HasValue();
Maybe<T> Bind(Func<T, Maybe<T>> f);
}
class Just<T> : Maybe<T>
{
private T _val;
public Just(T val) // <- Unit
{
_val = val;
}
#region Maybe implementation
public T Value ()
{
return _val;
}
public bool HasValue() { return true; }
public Maybe<T> Bind (Func<T, Maybe<T>> f) // <- Bind
{
return f (_val);
}
#endregion
}
class Nothing<T> : Maybe<T>
{
public Nothing() {} // <- Unit
#region Maybe implementation
public T Value ()
{
return default(T);
}
public bool HasValue() { return false; }
public Maybe<T> Bind (Func<T, Maybe<T>> f)
{
return new Nothing<T>(); // don't care
}
#endregion
}
class MainClass
{
public static void Main (string[] args)
{
Maybe<int> m = new Just<int> (20); // <- unit, technical the constructor
var res = m.Bind (x => new Just<int> (x + 4))
.Bind (x => new Just<int> (x * 100))
.Bind (x => {
Console.WriteLine ("Value at this stage is: " + x.ToString()); // did something but didn't change the value...
return new Just<int> (x);
})
.Bind (x => x >= 2400 ? (Maybe<int>)new Nothing<int> () : (Maybe<int>)new Just<int> (x));
if (res.HasValue())
Console.WriteLine (res.Value());
else
Console.WriteLine ("no value present");
Maybe<int> m2 = new Just<int> (20);
var res2 = m2.Bind (x => new Just<int>(x - 10))
.Bind (x => new Just<int>(x * 100))
.Bind (x => {
Console.WriteLine ("Value at this stage is: " + x.ToString());
return new Just<int> (x);
})
.Bind (x => x >= 2400 ? (Maybe<int>)new Nothing<int> () : (Maybe<int>)new Just<int> (x));
if (res2.HasValue())
Console.WriteLine (res2.Value());
else
Console.WriteLine ("no value present");
Maybe<int> m3 = new Just<int> (0);
var res3 = m3.Bind (x => x == 0 ? (Maybe<int>)new Nothing<int> () : (Maybe<int>)new Just<int> (x))
.Bind (x => new Just<int> (50 / x));
if (res3.HasValue ())
Console.WriteLine (res3.Value ());
else
Console.WriteLine ("Failed to divide by 0");
Maybe<int> m4 = new Just<int> (10);
var res4 = m4.Bind (x => x == 0 ? (Maybe<int>)new Nothing<int> () : (Maybe<int>)new Just<int> (x))
.Bind (x => new Just<int> (50 / x));
if (m4.HasValue ())
Console.WriteLine (res4.Value ());
else
Console.WriteLine ("Failed to divide by 10");
/*
Value at this stage is: 2400
no value present
Value at this stage is: 1000
1000
Failed to divide by 0
5
*/
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment