7 ms·
so monads are just a way to define an api ? so anything that is like this : values = ['coffee','water'] AfterWebSocket = values.sendToWebSocket() AfterWebSo
by wrong_variable 10y ago
so 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 :(
- spion 10y agoYeah, its about the type / interface / protocol. But they really are very, very useful. There are just so many problems that can be solved with it. For example there can be a GraphQL monad. Instead of Promise.all you would use GraphQL.parallel(otherMonads), and the implementation can transform that to a single request to the server instead of multiple ones. Similarly there can be an ORM monad that avoids the n+1 queries problem. parallel(Users.get(id)).chain(users => ...) will transform the parallel query to a single SELECT ... IN query. Also, have you tried passing the current user around in server side code, everywhere? Its really tedious to do, and Reader solves that! A monad transformer is (more or less) a function that takes a monad class and returns a new monad class (yes thats the class object, not an instance). So if for example Future were a monad, and you wanted to add Reader functionality, you would create a new class PromiseWithReader: var FutureWithReader = ReaderT(Future) Now you can use this monad to do both getState() and async IO operations within its chained functions. function getUserPosts() { return getState() .chain(state => Posts.getForUserId(state.user.id)) // cheating a bit here } in the route handler: getUserPosts.runWith({user: req.currentUser}) .fork(posts => res.json(posts)) The cool part is you can use getState() at any time to get the state. This will work no matter how deep your functions are: the example above is just with a single function, but that function can call another, which calls another, which calls getState() to get the user. But there is still no need to pass that user through all those calls. And if you use something like a State monad, you'll even be able to modify the contents of the state. p.s. Future implementation, based on robotlolita's minimal Future class: https://gist.github.com/spion/b433a665ca51d6c38e9f https://gist.github.com/spion/b433a665ca51d6c38e9f
- wrong_variable 10y agohey spion ! I read your post and sent you some messages on gitter, it seems you do not use gitter a lot :(
- spion 10y agoSorry about that. Here is an implementation of ReaderT, how it can transform a Future to provide "local readonly state", and a usage example: https://gist.github.com/spion/b433a665ca51d6c38e9f https://gist.github.com/spion/b433a665ca51d6c38e9f Since its JS, I also added automatic lifting, just to annoy Haskell programmers ;)