Last active
December 26, 2015 20:29
-
-
Save matthewphilyaw/0d10acf7b675c87cccbe to your computer and use it in GitHub Desktop.
Maybe monad in C#
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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