Created
April 7, 2013 11:28
-
-
Save dtchepak/5330109 to your computer and use it in GitHub Desktop.
I have no idea what I'm doing.
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
public class STRunner { | |
private class STToken { } | |
public A RunST<A>(ISTScope<A> scope) { | |
return scope.Get<STToken>().UnsafeRun(new STToken()); | |
} | |
} | |
public interface ISTScope<A> { | |
ST<S, A> Get<S>(); | |
} | |
public class ST<S, A> { | |
private readonly Func<S, Tuple<A, S>> _mutableOp; | |
internal A UnsafeRun(S state) { return _mutableOp(state).Item1; } | |
public ST(Func<S,Tuple<A,S>> mutableOp) { | |
_mutableOp = mutableOp; | |
} | |
public ST<S, C> SelectMany<B,C>(Func<A, ST<S, B>> f, Func<A, B, C> selector) { | |
return new ST<S, C>(s => { | |
var stateAndA = _mutableOp(s); | |
var stB = f(stateAndA.Item1); | |
var stateAndB = stB._mutableOp(stateAndA.Item2); | |
return Tuple.Create(selector(stateAndA.Item1, stateAndB.Item1), stateAndB.Item2); | |
}); | |
} | |
} | |
public class STRef<S, A> { | |
private A value; | |
public STRef(A a) { value = a; } | |
public ST<S, A> Read() { | |
return new ST<S, A>(s => Tuple.Create(value, s)); | |
} | |
public ST<S, Unit> Write(A a) { | |
return new ST<S, Unit>(s => { | |
value = a; | |
return Tuple.Create(new Unit(), s); | |
}); | |
} | |
} | |
public class STScope : ISTScope<int> { | |
public ST<S, int> Get<S>() { | |
var v = new STRef<S, int>(5); | |
return | |
from a in v.Read() // a = 5 | |
from b in v.Write(a*10) // v <- 50 | |
from c in v.Read() // c = 50 | |
select a + c; // return: 55 | |
} | |
} | |
[Test] | |
public void TestST() { | |
var result = new STRunner().RunST(new STScope()); | |
result.ShouldBe(55); | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment