Skip to content

Instantly share code, notes, and snippets.

@igstan
Last active December 11, 2015 11:58
Show Gist options
  • Save igstan/4597568 to your computer and use it in GitHub Desktop.
Save igstan/4597568 to your computer and use it in GitHub Desktop.
var result = function (a) {
return function (state) {
return { value: a, state: state };
};
};
var sequence = function (/* monadicActions..., continuation */) {
var args = [].slice.call(arguments);
var monadicActions = args.slice(0, -1);
var continuation = args.slice(-1)[0];
return function (state) {
var initialState = { values: [], state: state };
var r = monadicActions.reduce(function (state, action) {
var result = action(state.state);
var values = state.values.concat(result.value);
return { values: values, state: result.state };
}, initialState);
var values = r.values.filter(function (value) {
return value !== undefined;
});
return continuation.apply(this, values)(r.state);
};
};
var memoize = function (fn) {
return function (a) {
return function (cache) {
if (a in cache) {
console.log("Retrieving from cache:", a);
return result(cache[a])(cache);
} else {
// Clone the cache and add the new value to it.
var newCache = Object.create(cache);
newCache[a] = fn(a);
return result(newCache[a])(newCache);
}
};
};
};
var memo = memoize(function (a) {
return a * 2;
});
var initialCache = {};
var result0 = memo(5)(initialCache);
console.log(result0);
var result1 = memo(4)(result0.state);
console.log(result1);
var result2 = memo(5)(result1.state);
console.log(result2);
var result3 = memo(4)(result2.state);
console.log(result3);
// Using the sequence abstraction, which is basically an imitation of
// Haskell's do notation.
var cacheComputations = sequence(
memo(5),
memo(4),
memo(5),
memo(4),
function (a, b, c, d) {
console.log(a, b, c, d);
return result(a * b * c * d);
}
);
console.log( cacheComputations(initialCache) );
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment