Please forgive me, I'll do my best to describe what I am looking for. I don't have a name for it, so it makes it that much more difficult.
Looking at libraries such as Folktale and monet.js, I like being able to chain operations with map
without null-checking or if
statements, using e.g. Maybe
, Either
, Task
.
I am wondering whether a similar construct exists to solve the following problem:
map
ping a function on a Maybe.Nothing
)In other words, I'm looking for something similar to Maybe
which holds a value and maps a function on Just
but ignores a function mapped on Nothing
, and you can extract the value. I'm looking for something that holds an input and an initial null
result. When you map
a function, it runs the function on the input only if result
is null. If the function returns a value, that becomes the result and any other functions that are mapped are ignored. Finally, you can extract the result.
In imperative programming, this might look like:
var result1 = function1(input);
if (result1) {
return result1;
}
var result2 = function2(input);
if (result2) {
return result2;
}
// and so on.
Instead, I'd like to construct something along the lines of
Something(input).map(function1).map(function2).result()
or
compose(result, map(compose(function2, function1))(Something(input))
Does such a construct exist? Does it have a name? Even if this doesn't exist and I could write it myself, I'm at a loss as to what to call it. Suggestions welcome.
Thanks for your help!
UPDATE
Following the solution by @Bergi I used Maybe.orElse
. I wrote a little helper called ShortCircuit
, which I am posting below in case anyone finds this useful.
import Maybe from "data.maybe";
const ShortCircuit = function(input, result) {
this.input = input;
this.result = result;
};
ShortCircuit.of = function(input, f) {
return new ShortCircuit(input, Maybe.fromNullable(f(input)));
};
ShortCircuit.prototype.orElseMaybe = function(f) {
return new ShortCircuit(this.input, this.result.orElse(() => Maybe.fromNullable(f(this.input))));
};
ShortCircuit.prototype.get = function() {
return this.result.get();
};
export default ShortCircuit;
And here is how you use it:
const result = ShortCircuit.of(input, f1).orElseMaybe(f2).orElseMaybe(f3).get();
Suggestions for improvement are welcome.
What you are looking for is known as the Alternative
type class in Haskell. I have not yet found1 a JS library implementing it, though there is support for it in PureScript and a discussion about specifying it in FantasyLand.
Regardless, I've found a function in Folktale that does exactly what you want: Maybe's orElse
. You'd use it like this:
Something(input).orElse(function1).orElse(function2).get() // `get` throws when all failed
Even better, orElse
is available not only for Maybe
but also on Either
, Validation
and Task
!
The getOrElse
method, known as orElse
in Monet.js, is not really helpful as it wouldn't execute your "handlers" only in the case of a fail. You can implement your own Alternative
though using the cata
method.
1: Googling "JS alternative" is not really helpful either, even when you know the name :-)
Oh, and just in case you are using promises, there's always the .catch(…)
method which has broad (ES6-backed) support.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With