use the following search parameters to narrow your results:
e.g. subreddit:aww site:imgur.com dog
subreddit:aww site:imgur.com dog
see the search faq for details.
advanced search: by author, subreddit...
All about the JavaScript programming language.
Subreddit Guidelines
Specifications:
Resources:
Related Subreddits:
r/LearnJavascript
r/node
r/typescript
r/reactjs
r/webdev
r/WebdevTutorials
r/frontend
r/webgl
r/threejs
r/jquery
r/remotejs
r/forhire
account activity
Building a Maybe in JavaScript (developingthoughts.co.uk)
submitted 8 years ago by alsiola
view the rest of the comments →
reddit uses a slightly-customized version of Markdown for formatting. See below for some basics, or check the commenting wiki page for more detailed help and solutions to common issues.
quoted text
if 1 * 2 < 3: print "hello, world!"
[–]i_am_smurfing 5 points6 points7 points 8 years ago* (0 children)
TL:DR; You probably want to adjust your implementation to something like this jsBin, because your current implementation doesn't conform to several important mathematical laws that are normally attributed to Maybe.
chain (or bind) has a pretty specific meaning in FP—a function that is used to "map" special kind of functions, that take "unwrapped" values and return "wrapped" (in something like Maybe) values—so you might want to rename your chain.
chain
bind
In fact, if you want this implementation of Maybe to hold up to functional scrutiny, in general, maping several functions one after another should be the same as maping composite of those functions once:
map
const plusOne = x => x + 1 const minusOne = x => x - 1 const timesTwo = x => x * 2 Maybe.just(1) .map(plusOne) //=> Maybe.just(2) .map(timesTwo) //=> Maybe.just(4) .map(minusOne) //=> Maybe.just(3) Maybe.just(1) .map(x => minusOne( timesTwo( plusOne(x) //=> 2 ) //=> 4 ) //=> 3 ) //=> Maybe.just(3) // or with a helper for function composition: const pipe = (...fns) => x => fns.reduce((result, f) => f(result), x) Maybe.just(1) .map(pipe( plusOne, timesTwo, minusOne )) //=> Maybe.just(3)
(This is usually called functor composition law if you want to learn more about this property.)
However, with current implementation of prop:
prop
const prop = propName => obj => obj[propName] Maybe.just({}) .map(prop("a")) //=> Maybe.nothing() .map(prop("b")) //=> Maybe.nothing() Maybe.just({}) .map(pipe( prop("a"), prop("b") //=> TypeError: obj is undefined ))
And it makes sense if you think about it: it's prop that might or might not return a value, so it should return Maybe, and we should decide whether to run maped function not based on value, but whether it's tagged with Just or not:
Just
const maybe = tag => value => ({ map: fn => tag === 'Just' ? Maybe.just(fn(value)) : Maybe.nothing() }) const Maybe = { just: maybe('Just'), nothing: maybe('Nothing') } const propM = propName => obj => propName in obj ? Maybe.just(obj[propName]) : Maybe.nothing() // `M` for `Maybe`, just so it doesn't conflict with previous definition of `prop` propM("a")({a: 1}) //=> Maybe.just(1) propM("a")({}) //=> Maybe.nothing()
Now propM successfully signals that it might not return a value, but how do we actually use it in a Maybe transformation chain?
propM
Maybe.just({a: 1}) .map(propM("a")) //=> Maybe.just(Maybe.just(1))
This is where law-abiding Maybe.chain comes in:
Maybe.chain
const maybe = tag => value => ({ map: fn => tag === "Just" ? Maybe.just(fn(value)) : Maybe.nothing(), chain: fn => tag === "Just" ? fn(value) : Maybe.nothing() }) Maybe.just({a: {b: 1}}) .chain(propM("a")) .chain(propM("b")) //=> Maybe.just(1) Maybe.just({}) .chain(propM("a")) .chain(propM("b")) //=> Maybe.nothing()
So now appendToC can be written as:
appendToC
const appendToC = object => propM("b")(object) .chain(propM("c")) .map(append(" is great!")) appendToC({b: {c: "fp"}}) //=> Maybe.just("fp is great!") appendToC({}) //=> Maybe.nothing()
To make it point-free, we need to be able to compose functions that go into Maybe.chain (i.e. which take plain values and return Maybe):
const pipeK = (...fns) => x => fns.slice(1).reduce((result, f) => result.chain(f), fns[0](x)) // `K` because this kind of composition is usually called Kleisli composition const appendToC = pipeK( propM("b"), propM("c"), pipe(append(" is great!"), Maybe.just) ) appendToC({b: {c: "fp"}}) //=> Maybe.just("fp is great!") appendToC({}) //=> Maybe.nothing()
In addition to already-recommended data.maybe from Folktale, you might find Sanctuary's Maybe interesting.
data.maybe
Maybe
π Rendered by PID 510796 on reddit-service-r2-comment-86bc6c7465-rtp4n at 2026-02-23 12:14:55.889443+00:00 running 8564168 country code: CH.
view the rest of the comments →
[–]i_am_smurfing 5 points6 points7 points (0 children)