-
-
Save DrBoolean/da8a21e2058359f6c332 to your computer and use it in GitHub Desktop.
[1,2,3].map(x => x+1) | |
// [2, 3, 4] | |
[1,2,3].map(x => [x+1]) | |
// [[2], [3], [4]] | |
[1,2,3].chain(x => [x+1]) | |
// [2, 3, 4] | |
[1,[2],3].chain(x => [x+1]) | |
// [2, [3], 4] | |
var users = [{friends: ['sara', 'ajit']}, {friends: ['ross']}] | |
users.map(x => x.friends) | |
// [["sara", "ajit"], ["ross"]] | |
users.chain(x => x.friends) | |
// ["sara", "ajit", "ross"] | |
// assumes [].prototype has been extended with chain. | |
Promise.of(2).map(x => x + 1) | |
// Promise(3) | |
Promise.of(2).chain(x => Promise.of(x + 1)) | |
// Promise(3) | |
Promise.of(2).chain(x => Promise.of(Promise.of(x + 1))) | |
// Promise(Promise(3)) | |
http.get('/current_user').map(u => http.get('/todos', {user_id: u.id})) | |
// promise of promise of todos | |
http.get('/current_user').chain(u => http.get('/todos', {user_id: u.id})) | |
// promise of todos | |
Maybe.of(1).map(x => x+1) | |
// Just(2) | |
Maybe.of(null).map(x => x+1).map(x => x / 2) | |
// Nothing | |
Maybe.of(1).map(x => Maybe.of(x+1)) | |
// Just(Just(2)) | |
Maybe.of(1).chain(x => Maybe.of(x+1)) | |
// Just(2) | |
Maybe.of(null).chain(x => Maybe.of(x+1)) | |
// Nothing | |
getProp('user', {user: {name: 'bob'}}).map(u => getProp('name', u)).map(n => n.toUpperCase()) | |
// Just(Just('BOB')) | |
getProp('user', {user: {name: 'bob'}}).chain(u => getProp('name', u)).map(n => n.toUpperCase()) | |
// Just('BOB') | |
getProp('user', {}).chain(u => getProp('name', u)).map(n => n.toUpperCase()) | |
// Nothing | |
EventStream.of("hello").map(x => x + " world") | |
EventStream.of("hello").chain(x => EventStream.of(x + " world")) | |
("input").keyDown().map(e => e.target.value) | |
// stream of values | |
("input").keyDown().map(e => search(e.target.value)) | |
// stream of stream of search results | |
("input").keyDown().chain(e => search(e.target.value)) | |
// stream of search results | |
oh yeah.
const getProp = (key, obj) => Maybe.fromNullable(obj[key])
imports would be:
https://github.com/fantasyland/fantasy-promises or https://github.com/folktale/data.task
rxjs or bacon event streams
Maybe from https://github.com/folktale/data.maybe
@DrBoolen "Monads in a minute" love it. What is "user" on line 14?
My brain is slowly wrapping itself around this concept now.
The Maybe monad disturbs me a bit though - on line 37 and line 40, the map can return either a Just or a Nothing, but dealing with the array functor, we've learned that map must preserve is it's type and size. Why doesn't the maybe monad seem to obey this same restriction? Is it because it's sort of an enum-like thing in Haskell?
@mpj I updated user to be more correct and self explanatory.
Good eye on the Maybe. It is indeed an enum or "sum type". Which means it can be Just | Nothing and it still holds its structure. Kind of like a List of Cons|Nil.
I usually use a simplified version for teaching which looks something like:
const Maybe = x => ({
map: f => Maybe(x ? f(x) : x),
chain: f => x ? f(x) : Maybe(x),
})
The reason the simplified version is a little incorrect is that we should never be inspecting the value of x
within map/chain
- it should just mechanically apply in an expected way. Inspection of x
breaks parametric polymorphism or universal qualification of the value inside of a functor.
chain
is also calledflatMap
which makes more sense. It's also calledbind
/>>=
.of
is calledunit
. It just puts anything in the type regardless of what the constructor wants.