Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Applicative instances composition in vanilla js
function composeFunctor(f, g) {
function map(h, fga) {
return f.map(ga => g.map(h, ga), fga)
}
return { map }
}
function composeApplicative(f, g) {
const { map } = composeFunctor(f, g)
function ap(fgab, fga) {
return f.ap(f.map(h => ga => g.ap(h, ga), fgab), fga)
}
function of(a) {
return f.of(g.of(a))
}
return { map, ap, of }
}
// Example
// The Applicative instance for Array
const arr = {
map(f, fa) {
return fa.map(f)
},
of(a) {
return [a]
},
ap(fab, fa) {
return fab.reduce((acc, f) => acc.concat(fa.map(f)), [])
}
}
// The Applicative instance of Maybe
const maybe = {
map(f, fa) {
return fa == null ? null : f(fa)
},
of(a) {
return a;
},
ap(fab, fa) {
return fab == null ? null : this.map(fab, fa)
}
}
// Compose them!
const x = [" foo ", null, "bar "];
// x.map(v => v.trim()) // BOOM! Explodes on null
composeFunctor(arr, maybe).map(v => v.trim(), x) // ["foo", null, "bar"]
const f = v => v.trim()
const g = v => v.startsWith("b")
composeApplicative(arr, maybe).ap([f, g], x) // ["foo", null, "bar", "false", null, "true"]
@gabro

This comment has been minimized.

Copy link
Owner Author

gabro commented Nov 21, 2016

Maybe is encoded very naively as a native js value. The "trick" is checking for null (or undefined) in its map function.

@lambdista

This comment has been minimized.

Copy link

lambdista commented Nov 21, 2016

Still, really nice!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.