Created
June 22, 2011 10:07
-
-
Save kana/1039805 to your computer and use it in GitHub Desktop.
Monad in C# (work in progress)
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 Microsoft.VisualStudio.TestTools.UnitTesting; | |
using System; | |
using MonadSharp; | |
namespace Test | |
{ | |
[TestClass()] | |
public class Test | |
{ | |
[TestMethod()] | |
public void MaybeTest() | |
{ | |
AreEqual(Just(10), Just(10)); | |
AreEqual(Just(5), Just(10).Bind(a => Divide(a, 2))); | |
AreEqual(Nothing(), Just(10).Bind(a => Divide(a, 0))); | |
AreEqual(Nothing(), Just(10).Bind(a => Divide(a, 0)).Bind(a => Divide(a, 2))); | |
AreEqual(Nothing(), Just(10) | (a => Divide(a, 0)) | (a => Divide(a, 2))); | |
} | |
private void AreEqual(Maybe<int> expected, Maybe<int> actual) | |
{ | |
Assert.AreEqual(expected.Look(null, x => (object)x), actual.Look(null, x => (object)x)); | |
} | |
private Maybe<int> Divide(int dividend, int divisor) | |
{ | |
if (divisor == 0) | |
return Nothing(); | |
else | |
return Just(dividend / divisor); | |
} | |
private Just<int> Just(int plainValue) | |
{ | |
return new Just<int>(plainValue); | |
} | |
private Nothing<int> Nothing() | |
{ | |
return Nothing<int>.Value; | |
} | |
} | |
} |
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; | |
using System.Collections.Generic; | |
using System.Linq; | |
using System.Text; | |
namespace MonadSharp | |
{ | |
class Program | |
{ | |
static void Main(string[] args) | |
{ | |
} | |
} | |
public abstract class Monad<TValue, TMonad> where TMonad : Monad<TValue, TMonad> | |
{ | |
public abstract TMonad Bind(Func<TValue, TMonad> other); | |
public static TMonad operator |(Monad<TValue, TMonad> a, Func<TValue, TMonad> b) | |
{ | |
return a.Bind(b); | |
} | |
} | |
public class Maybe<T> : Monad<T, Maybe<T>> | |
{ | |
protected T Value {get; set;} | |
public override Maybe<T> Bind(Func<T, Maybe<T>> other) | |
{ | |
if (this == Nothing<T>.Value) | |
return this; | |
else | |
return other(this.Value); | |
} | |
public TResult Look<TResult>(TResult fallbackValue, Func<T, TResult> f) | |
{ | |
if (this == Nothing<T>.Value) | |
return fallbackValue; | |
else | |
return f(this.Value); | |
} | |
public T Look(T fallbackValue) | |
{ | |
return Look(fallbackValue, x => x); | |
} | |
} | |
public class Nothing<T> : Maybe<T> | |
{ | |
private static Nothing<T> theNothing = new Nothing<T>(); | |
public static new Nothing<T> Value {get {return theNothing;}} | |
private Nothing() | |
{ | |
} | |
} | |
public class Just<T> : Maybe<T> | |
{ | |
public Just(T plainValue) | |
{ | |
Value = plainValue; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment