// Chris Done
// Created: 13 April, 2008
// Last modified: 13 April, 2008
/* State monad in Haskell */
// Simple tuple
function tuple(x,y) { return function(f) { return f(x,y); } }
function fst(t) { return t(function(x,y) { return x; }); }
function snd(t) { return t(function(x,y) { return y; }); }
// Monadic operations
// Equivalent to >>=
function bindM(m ,k)
{
return function (s) {
tmp = m(s);
a = fst(tmp); s_ = snd(tmp);
return k(a)(s_);
}
}
// Equivalent to >>
function thenM(m,k) {
return bindM(m,function(_){return k;});
}
function returnM(v) {
return function (s) {
return tuple(v,s);
}
}
function evalS(m,s) {
return fst(m(s));
}
function getS(s) {
return tuple(s,s);
}
function putS(s) {
return function(_) {
return tuple(null,s);
}
}
/* Simple examples: */
function print(s) { document.write("<p>" + s + "</p>"); }
print(
evalS(
thenM( putS("Woo!") , bindM( getS , returnM ) )
,2));
// Output: "Woo!"
print(
evalS(
thenM( putS("Woo!") , getS )
,2));
// Output: "Woo!"
print(
evalS(
thenM( bindM( getS , function(n) { return putS(n+1); } )
, getS
)
,1));