- Monad
- Promise
- Observable
- Demo
EcmaScript5
function(x){return x+1}
EcmaScript6
x=>x+1
-- HM(Hindley-Milner) type signature
liftM :: (Monad m) => (a -> b) -> m a -> m b
-- ^type restrict ^function ^ ^return
-- ^curry^
[1,2,3].map(x=>x+1)
// => [2,3,4]
[1,2,3].filter(x=>x/2==0)
// => [2]
[1,2,3].reduce((acc,n)=>acc+n)
// => 6
- Method -> Function
- First Class Function
let toUpperCase = x => x.toUpperCase() // <- 1
let map = (f, col) => col.map(f) // <- 1
map(toUpperCase, ["hello", "world"])
// ^2
//=> ["HELLO", "WORLD"]
// map:: (String s) => (s -> s) -> [s] -> [s]
map(toUpperCase, ["hello", "world"])
functor is mapable!
"hello" + "world" // <-- concat
// => "helloworld"
"hello" + "" // <-- identity
// => "hello"
("hello" + "world") + "!" == "hello" + ("world" + "!") // <-- associative
// => true
Monoid is concatable!
- Functor is mapable!
- Monoid is concatable!
A monad is just a monoid in the category of endofunctors, what’s the problem?
- Catergory -> “Type”
- Functor -> “Mapable”
- Monoid -> “Concatable”
“A monad is just a concatable in Type of mapable, what’s the problem?”
// concat :: (Monad m) => m m x -> m x
[1].concat([2]) -> [1,2]
// concat Array Array -> Array
T concat T -> T
type G[X] = T[T[X]]
G = T compose T = T.T
T.T[X] = G[X] = T[T[X]]
concat(T.T).T == T.concat(T.T)
- u -> concat
- T(u) -> lift(flat)
pure(T[X]) == T[T[X]]
- n -> pure
- T(n) -> lift(pure)
liftM :: (Monad m) => (a -> b) -> m a -> m b
const when = require('when')
// readJSON :: (Promise p, String s, Object o) => (s -> o) -> p s-> p o
let readJSON = when.lift(JSON.parse)
readJSON(when('{hello: "world"}'))
.then(x=>console.log(x))
.catch(e=>console.error(e.message));
// => Unexpected token h in JSON at position 1
or simply try something and wrap result in Promise
try(JSON.parse, '{hello: "world"}')
.then(x=>console.log(x))
.catch(e=>console.error(e.message));
// => Unexpected token h in JSON at position 1
foldM :: (Monad m) => (a -> b -> m a) -> a -> [b] -> m a
// reduce :: (Promise p, Number n, Object o) => [n] -> (o -> n -> p o) -> o -> p o
when.reduce([1,2,3], (acc, n) => rest(URL + n).then(o=>merge(acc, o)), 0)
var allRes = {}
$.get('url1', (res1) =>
$.get('url2', (res2) =>
$.get('url3', (res3) =>
allRes = merge(res1, res2, res3))
)
)
let futureWorld = new Promise(resolve=>{
setTimeout(()=>resolve("world"), 1000)
})
futureWorld
.then(world=>new Promise(resolve=>{
setTimeout(()=>resolve("hello"+world), 1000)
}))
.then(x=>console.log(x))
// 2secs later => helloworld
- first
then
isflatMap
- second
then
ismap
imperative
var acc = 0
for(var n of [1,2,3,4]) {
acc +=n
}
functional
[1,2,3,4].reduce((acc,x)=>acc+x)
imperative accumulate value on time
var acc = 0;
$('input').onChange(_=>acc+=_)
Single Item | Multiple Items | |
---|---|---|
synchronous | getData():T | getData():List[T] |
asynchronous | getData():Future[T] | getData():Observable[T] |
Thanks
We are hiring