Result
folktale.result
- Result is like an
Either
, modeling either a value or an error. - It is a Monad as it has a
chain
property. - It will be either a successful value:
Result.OK
, or an error:Result.error
. - The value will be stored in the property
value
, whether Ok or an error. - Will have either an
isOK
orisError
property, but these are deprecated.
Creation
Result.Ok(value);
Result.Error(value);
Extracting Result
getOrElse
It also offers a getOrElse
method which can be used for extracting a value with a default if the result is an error:
const value = result.getOrElse(DEFAULT_VALUE);
Transformation
matchWith
To map the result to a different function depending on whether it is a Result.Ok
or a Result.Error
:
result.matchWith({
Ok: ({value}) => `Value: ${value}`,
Error: () => `No value`,
})
map
To perform an action on the result only if it is OK, map
can be used. If the result is a Result.Error
, it will just return that Result.Error
, but if the result is Result.Ok
, its value will be passed in to the function supplied, and it will return whatever the function returns as the value
of a Result.Success
.
const value = result.map(example);
chain
However, if the function supplied to map
also returns a Result
, chain
should be used instead to avoid a nested Result
. In this case it is assumed that the value returned will be a Result
, so whatever is returned from the function is returned as is, without being wrapped in a Result
.
const value = result.chain(example);
orElse
To perform an action on the result only if it is an Error, orElse
_ can be used. _If the result is a Result.Ok
, it will just return that Result.Ok
, but if the result is Result.Error
, its value will be passed in to the function supplied, and it will return whatever the function returns. For consistency it should return a Result
, unless it throws.
const value = result.orElse(example);
Introspection
To devine whether a Result
is an Ok
or an Error
, hasInstance
is used:
Result.Ok.hasInstance(result);
Result.Error.hasInstance(result);
Examples
Basic Chaining
const gt10 = gt(__, 10);
const alpha = (n) => {
const result = isNumber(n) ?
Result.Ok(n) :
Result.Error(`Value wasn't a number`);
return result;
}
const beta = (n) => {
const result = gt10(n) ?
Result.Ok(n) :
Result.Error(`Value wasn't > 10`);
return result;
}
const successfulResult = alpha(22).chain(beta);
const failingFirstResult = alpha('a').chain(beta);
const failingSecondResult = alpha(6).chain(beta);
console.log('Success', successfulResult.value); // 22
console.log('Success - was OK', Result.Ok.hasInstance(successfulResult)); // true
console.log('Success - was Error', Result.Error.hasInstance(successfulResult)); // false
console.log('failedFirst', failingFirstResult.value); // Value wasn't a number
console.log('failedFirst - was OK', Result.Ok.hasInstance(failingFirstResult)); // false
console.log('failedFirst - was Error', Result.Error.hasInstance(failingFirstResult)); // true
console.log('failedSecond', failingSecondResult.value); // value wan't > 10
console.log('failedSecond - was OK', Result.Ok.hasInstance(failingSecondResult)); // false
console.log('failedSecond - was Error', Result.Error.hasInstance(failingSecondResult)); // true