4 ms·
The reader monad is like read-only thread-local storage. (State or ST would be thread local storage). It provides a command to get the "current state" functi
by spion 10y ago
The reader monad is like read-only thread-local storage. (State or ST would be thread local storage). It provides a command to get the "current state"
function f() {
var m = getState().chain(state => {
// ...
})
return m;
}
or with generators acting like do syntax replacement:
var f = wrapped(function* () {
var state = yield getState();
// ...
return;
});
At the end you get an object that contains an unexecuted sequencing of computations that you can run with any state. For example you could run it from a HTTP route handler with the current user contained in the "state":
var m = f();
m.runWith({currentUser: request.user})
and now you have access to the user without passing it around everywhere.
All the other analogies in this thread are wrong in terms of what the real API looks like. The real API looks almost exactly like Promises, with `chain` instead of `then`.
This in turn also explains why monad transformers are so important. Having access to just the current user w/o passing it around isn't very useful if e.g. you can't do IO, but having both - now we're talking!
- wrong_variable 10y agoI do not understand how the reader monad is different than promise. It seems the reader monad just delays execution of some code until you call 'runWith' and you can define state variables throughout your code before calling runWith.
- spion 10y agoThats precisely what it does, yes. Its different than a promise because the implementation is different (everything is done synchronously, and getState() returns an action object which then the implementation works on. The result of doing runWith() is also immediately available (not possible with async IO): var result = m.runWith(...) Other than that its almost exactly the same. And so are other monads. The Array monad (that is, if JS arrays actually had that method, which they don't) var m = [1,2,3] .chain(x => [x, x * 10]) .chain(y => y < 2 ? [] : [y]) result: [10,2,20,3,30] Same API (monad), totally different functionality.
- wrong_variable 10y agoso monads are just a way to define an api ? so anything that is like this : values = ['coffee','water'] AfterWebSocket = values.sendToWebSocket() AfterWebSocket.compute (eachValue => x*2) is that it ?
- spion 10y agoIt has to be the chain method and it has to act in such a way that you pass a function that returns an object of the same type. For array chain takes a function that returns an array. For promises, chain takes a function that returns a promise object. For Reader, chain takes a function that returns another reader object. Here is a complete class Reader: class Reader { constructor(computation) { this.computation = computation; } runWith(data) { return this.computation(data) } chain(readerReturningFn) { return new Reader(data => readerReturningFn(this.computation(data)) .runWith(data)) } static of(val) { return new Reader(data => val) } static getState() { return new Reader(data => data) } } Here is how you can use it: var r = Reader.of(5).chain(x => Reader.getState().chain(y => Reader.of(x + y))) r.runWith(2) > 7 For it to be useful, you want ReaderT, a monad transformer which takes another monad (such as Future) and creates a new monad that provides functionality from both. This gets fairly complicated fairly quickly :D But the result is also a monad, which means it will have the same familiar `chain` based API. And yes, monads in programming are this simple. Mathematical monads are a wider generalisation of computing monads (just like Iterable would be something more general in the real world, not "things with a next() method that acts like this"), but in terms of programming its a shared API (chain) that acts in a certain way (chains to another object of the same type and flattens one level, whatever that means for the concrete implementation)
- wrong_variable 10y agoSo its all just about types, ? More like a specs that if people follow the world would be a better place ? what is a monad transformer ? I understand your code - but fail to see why its so useful :(