Last active
November 21, 2016 13:04
-
-
Save gabro/261f3e29805c782bc5c12e376a9ab8fa to your computer and use it in GitHub Desktop.
Applicative instances composition in vanilla js
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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"] |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Still, really nice!