I may be misunderstanding you, but from your description, that more describes functors than it does monads. The difference being that in a monad, the `someFunc` you pass in is responsible for creating a new context (of the same monad type).
Pretending that javascript is immutable, I think it would probably look something more like
contextObj = monadBox(myObj)
// someContextReturningFunc gets myObj as its argument from contextObj and generates newContextObj
newContextObj = monadBind(contextObj, someContextReturningFunc)
newNewContextObj = monadBind(newContextObj, someOtherContextReturningFunc)
...
To make this more concrete, let's take the Maybe monad/functor in javascript and compare them. The Maybe monad is described by johnpmayer elsewhere here.
// Creating maybe "contexts"
maybeNothing = {maybe: "nothing"}; // maybeMonad holding nothing
maybeJust = function(x) { return {maybe: "just", just: x} }; // create a maybeMonad holding a (the '[a]' in the picture)
// Monadic bind
function maybeBind(maybeMonad, f) {
// maybeMonad is '[a]' in the picture
if (maybeMonad.maybe === "just") {
return f(maybeMonad.just); // expects f to return another maybeMonad '[b]'
} else {
return maybeNothing; // also '[b]' but the b value doesn't really exist
}
}
// Functor map
function maybeMap(maybeMonad, f) {
// maybeMonad is '[a]' in the picture
if (maybeMonad.maybe === "just") {
return maybeJust(f(maybeMonad.just)); // expects f to return a value without any maybe stuff ('a -> b')
// notice that the monad wrapping remains separate from f
} else {
return maybeNothing;
}
}
// Functor examples
//////
// possible values of 'f', note that maybe is not involved at all
function addOne(x) { return x + 1; }
// usage
console.log(maybeMap(maybeJust(1), addOne)); // returns maybeJust(2)
console.log(maybeMap(maybeNothing, addOne)); // returns maybeNothing
// Monad examples
//////
// possible values for 'f', notice x is what was contained in the maybe (not the maybe itself) and the return is a maybe
function maybeAddOneIfOdd(x) { return (x % 2 == 0) ? maybeNothing : maybeJust(x + 1); };
function maybeAddThree(x) { return maybeJust(x + 3); };
// usage
console.log(maybeBind(maybeJust(1), maybeAddThree)); // returns maybeJust(4)
console.log(maybeBind(maybeJust(1), maybeAddOneIfOdd)); // returns maybeJust(2)
console.log(maybeBind(maybeBind(maybeJust(1), maybeAddThree), maybeAddOneIfOdd)); // returns maybeNothing (due to 4 being even)
console.log(maybeBind(maybeBind(maybeJust(2), maybeAddOneIfOdd), maybeAddThree)); // returns maybeNothing because the first bind returned nothing
// and of course, composition
function maybeMultiplyThree(x) { return maybeJust(x * 3); }
function maybeMultiplyThreeThenAddOneIfOdd(x) {
return maybeBind(maybeMultiplyThree(x), maybeAddOneIfOdd);
}
console.log(maybeBind(maybeJust(1), maybeMultiplyThreeThenAddOneIfOdd)); // returns maybeJust(4)
console.log(maybeBind(maybeJust(2), maybeMultiplyThreeThenAddOneIfOdd)); // returns maybeNothing
Pretending that javascript is immutable, I think it would probably look something more like
To make this more concrete, let's take the Maybe monad/functor in javascript and compare them. The Maybe monad is described by johnpmayer elsewhere here. Edit: added some extra examples and comments