Monads/Writer monad: Difference between revisions

→‎ES5: updated writer monad to include intermediate values in log
(→‎ES5: updated writer monad to include intermediate values in log)
Line 17:
<lang JavaScript>(function () {
'use strict';
 
// START WITH THREE SIMPLE FUNCTIONS
 
// Square root of a number more than 0
function root(x) {
return Math.sqrt(x);
}
 
// Add 1
function addOne(x) {
return x + 1;
}
 
// Divide by 2
function half(x) {
return x / 2;
}
 
 
// DERIVE LOGGING VERSIONS OF EACH FUNCTION
 
function loggingVersion(f, strLog) {
return function (v) {
Line 46:
}
}
 
var log_root = loggingVersion(root, "obtained square root"),
 
log_addOne = loggingVersion(addOne, "added 1"),
 
log_half = loggingVersion(half, "divided by 2");
 
 
 
// UNIT/RETURN and BIND for the the WRITER MONAD
 
// The Unit / Return function for the Writer monad:
// 'Lifts' a raw value into the wrapped form
Line 66:
};
}
 
// The Bind function for the Writer monad:
// applies a logging version of a function
// to the contents of a wrapped value
// and return a wrapped result (with extended log)
 
// Writer a -> (a -> Writer b) -> Writer b
function writerBind(w, f) {
var writerB = f(w.value);,
v = writerB.value;
 
return {
value: writerB.valuev,
log: w.log + '\n' + writerB.log + ' -> ' + JSON.stringify(v)
};
}
 
// USING UNIT AND BIND TO COMPOSE LOGGING FUNCTIONS
 
// We can compose a chain of Writer functions (of any length) with a simple foldr/reduceRight
// which starts by 'lifting' the initial value into a Writer wrapping,
Line 93 ⟶ 94:
}, writerUnit(value));
}
 
var half_of_addOne_of_root = function (v) {
return logCompose(
Line 99 ⟶ 100:
);
};
 
return half_of_addOne_of_root(5);
})();</lang>
Line 105 ⟶ 106:
{{Out}}
 
<pre>{
<pre>{"value":1.618033988749895, "log":"Initial value: 5\nobtained square root\nadded 1\ndivided by 2"}</pre>
"value":1.618033988749895,
"log":"Initial value: 5\n
obtained square root -> 2.23606797749979\n
added 1 -> 3.23606797749979\n
divided by 2 -> 1.618033988749895"
}</pre>
9,659

edits