Skip to content

Instantly share code, notes, and snippets.

@homam
Created June 28, 2016 21:30
Show Gist options
  • Save homam/00353dcbaf9f3d32012b7b9a26b33a22 to your computer and use it in GitHub Desktop.
Save homam/00353dcbaf9f3d32012b7b9a26b33a22 to your computer and use it in GitHub Desktop.
const trace = (x, y) => {
console.log(x)
return y
}
const trace1 = x => trace(x, x)
const id = x => x
Promise.prototype.map = function(f) {
return this.then(x => {
const y = f(x)
if(y instanceof Promise)
throw 'Expected f :: a -> b but got a -> Promise b'
else
return y
})
}
Promise.prototype.bind = function(f) {
return this.then(x => {
const y = f(x)
if(y instanceof Function)
throw 'Expected f :: a -> Promise b but got a -> b'
if(y instanceof Promise)
return y
else
throw `Expected f :: a -> Promise b but got ${f}`
})
}
const swap = ([x, y]) => [y, x]
const wrap1 = (arrow, before, after, f) =>
arrow.arr(before).pipe(arrow.arrM(f)).pipe(arrow.arr(after))
const wrap12 = (arrow, before, after, f) => new arrow(x => {
let b = arrow.arr(before).run(x)
let y = arrow.arrM(id).pipe(arrow.arrM(f)).run(b)
return arrow.arrM(id).pipe(arrow.arr(after)).run(y)
})
const wrap2 = (arrow, before, after, f) =>
arrow.arr(before).fanout(arrow.arrM(f)).pipe(
arrow.arr(([x, y]) => {after([x, y]); return y }))
class Arrow {
constructor(T) {
// a b c -> a b' c' -> a (b,b') (c,c')
this.split = g => this.first().pipe(T.arr(swap)).pipe(g.first()).pipe(T.arr(swap))
// a b c -> a b c' -> a b (c,c')
this.fanout = g => T.arr(b => [b, b]).pipe(this.split(g))
}
}
class Func extends Arrow {
constructor(f) {
super(Func)
this.pipe = g => new Func(x => g.run(this.run(x)))
this.map = g => new Func(x => g(this.run(x)))
this.bind = g => g(this.run(x))
// a b c -> a (b,d) (c,d)
this.first = _ => new Func(([x, y]) => [f(x), y])
this.run = x => f(x)
}
}
Func.id = new Func(x => x)
Func.arr = f => new Func(f)
Func.arrM = f => new Func(f)
//console.log(new Func(x => 2 * x).first().run([2, 33]))
//console.log(new Func(x => 2 * x).split(new Func(x => x * 10)).run([2, 33]))
//console.log(new Func(x => 2 * x).fanout(new Func(x => x * 10)).run(3))
console.log(
wrap12(Func,
x => x*2,
x => x+1,
x => x * x / 2
).run(3)
)
console.log(wrap2(Func,
x => Date.now(),
([b, y]) => {
console.log(`${y} produced after ${Date.now() - b}`)
return "IGNORE IT"
},
x => x * 10
).run(3))
class Prom extends Arrow {
constructor(f) {
super(Prom)
this.pipe = g => new Prom(x => this.run(x).bind(y => g.run(y)))
this.map = g => new Prom(x => this.run(x).bind(g))
this.bind = g => new Prom(x => this.run(x).bind(g))
this.first = _ => new Prom(([x, y]) => this.run(x).map(x => [x, y]))
this.run = x => f(x)
}
}
Prom.id = new Prom(x => Promise.resolve(x))
Prom.arr = f => new Prom(x => Promise.resolve(f(x)))
Prom.arrM = f => new Prom(f)
wrap12(Prom,
x => x*2,
x => x+1,
x => Promise.resolve(x * x / 2)
).run(3)
//.map(x => console.log(`P = ${x}`))
wrap2(Prom,
x => Date.now(),
([b, y]) => {
console.log(`${y} produced after ${Date.now() - b}`)
return "IGNORE IT"
},
x => Promise.resolve(x * x / 2)
).run(3)
.map(x => console.log(`P = ${x}`))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment