Created
October 16, 2014 11:12
-
-
Save loosechainsaw/5b1286043c90fa1e428a to your computer and use it in GitHub Desktop.
IO Monad
This file contains hidden or 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 NUnit.Framework; | |
using System; | |
namespace Monads | |
{ | |
public class Unit{ | |
private Unit(){ | |
} | |
public static Unit Instance(){ | |
return value.Value; | |
} | |
private static Lazy<Unit> value = new Lazy<Unit>(() => new Unit() ); | |
} | |
public interface IIO<out T>{ | |
T PerformUnsafeIO(); | |
} | |
public class IO<T> : IIO<T>{ | |
public IO(Func<T> function){ | |
this.function = function; | |
} | |
public T PerformUnsafeIO(){ | |
return function(); | |
} | |
private Func<T> function; | |
} | |
public static class IOExtensions{ | |
public static IIO<T> Unit<T>(this Func<T> f){ | |
return new IO<T>(f); | |
} | |
public static IIO<U> Select<T,U>(this IIO<T> io, Func<T,U> map){ | |
return new IO<U>(() => map(io.PerformUnsafeIO())); | |
} | |
public static IIO<U> SelectMany<T,U>(this IIO<T> io, Func<T, IIO<U>> mapMany){ | |
return new IO<U>(() => | |
{ | |
return mapMany(io.PerformUnsafeIO()).PerformUnsafeIO(); | |
}); | |
} | |
public static IIO<V> SelectMany<T,U,V>(this IIO<T> io, Func<T, IIO<U>> mapMany, Func<T,U,V> map){ | |
return new IO<V>(() => | |
{ | |
var a = io.PerformUnsafeIO(); | |
var b = mapMany(a).PerformUnsafeIO(); | |
return map(a,b); | |
}); | |
} | |
} | |
public interface IConsoleWriter : IIO<Unit>{ | |
} | |
public class ConsoleWriter : IConsoleWriter{ | |
public ConsoleWriter(string text){ | |
this.text = text; | |
} | |
public Unit PerformUnsafeIO() | |
{ | |
Console.WriteLine(text); | |
return Unit.Instance(); | |
} | |
private string text; | |
} | |
[TestFixture] | |
public class MonadTests | |
{ | |
public IIO<Unit> WriteWorld(Unit unit){ | |
return new ConsoleWriter("World"); | |
} | |
[Test] | |
public void IOMonadSample() | |
{ | |
var a = new ConsoleWriter("Hello").SelectMany(WriteWorld).PerformUnsafeIO(); | |
var r = from x in new ConsoleWriter("Hello") | |
from z in WriteWorld(x) | |
select z; | |
r.PerformUnsafeIO(); | |
} | |
} | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment