Created
February 23, 2017 16:20
-
-
Save Gryff/d57ac28eadcb70bf2e116015f65b2313 to your computer and use it in GitHub Desktop.
Functors, Applicative Functors in Javascript
This file contains 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
// functors are computational contexts around values | |
// or, you could say they are boxes around values | |
// one instance of a functor is Maybe | |
// say you have a function that might return a value or undefined | |
function possiblyAValue() { | |
return Math.floor((Math.random() * 2)) === 0 ? undefined : { hey: { iAm: 'A value!' } } | |
} | |
// and you want to work with this return value, but don't want to throw an error if those properties aren't there | |
function getMyValue(myObject) { | |
return myObject.hey.iAm | |
} | |
// you would use a maybe functor | |
function maybe(value, fn) { | |
return value === undefined ? value : fn(value) | |
} | |
// maybe works by mapping over a value contained in a box, in this case the value can be undefined or an object | |
maybe(undefined, getMyValue) // undefined | |
maybe(ourObjectFromBefore, getMyValue) // 'A value!' | |
// now we can use the possiblyAValue function without checking for undefined | |
maybe(possiblyAValue(), getMyValue) | |
// the return value may be undefined or a value, so the return value itself is a functor | |
// maybe :: m a -> (a -> b) -> m b | |
// this means we can do maybes on maybes | |
// APPLICATIVE functors | |
// what if our maybe values held a function? | |
function possiblyAFunction() { | |
return Math.floor((Math.random() * 2)) === 0 ? undefined : endArgument | |
function endArgument(reason) { | |
return reason + ' and THAT is the end of that' | |
} | |
} | |
// we want to apply this to our value string, but we can't compose it | |
// we need an applicative functor | |
function maybeA(maybeFn, value) { | |
return maybeFn === undefined ? maybeFn : maybeFn(maybe(value)) | |
} | |
maybeA(undefined, undefined) // undefined | |
maybeA(undefined, ourObjectFromBefore) // undefined | |
maybeA(endArgument, undefined) // undefined | |
maybeA(endArgument, ourObjectFromBefore) // 'A value! and THAT is the end of that' | |
maybeA(possiblyAFunction(), possiblyAValue()) // undefined OR 'A value! and THAT is the end of that' | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment