Skip to content

Instantly share code, notes, and snippets.

@DrBoolean
Last active June 10, 2016 01:12
Show Gist options
  • Save DrBoolean/da8a21e2058359f6c332 to your computer and use it in GitHub Desktop.
Save DrBoolean/da8a21e2058359f6c332 to your computer and use it in GitHub Desktop.
monads in a minute
[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
@DrBoolean
Copy link
Author

@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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment