import { Option } from "https://deno.land/x/eitherway@0.10.0/lib/core/option.ts";
const { lift } = Option;
Use this to compose functions and Option
constructors
Allows interleaving a given chain of operations on instances of type
Option<T>
with (sort of) arbirtrary operations by lifting them into
an Option
context
This is useful in situations, where it's necessary to perform computations
on the wrapped value of type <T>
, but the available functions are
invariant over the provided map()
or andThen()
methods' parameters
Furthermore, it allows for composing functions with custom Option
constructors to preserve certain invariants
Examples
Example 1
Example 1
import { assert } from "./assert.ts";
import { Option, None, Some } from "./option.ts";
// Suppose this function is imported from a fancy library
function chainDivide(n: number, ...divisors: number[]) {
return divisors.reduce((acc, divisor) => acc /= divisor, n);
}
// These two live somewhere in your codebase
function getDivident(): Option<number> {
return Option.from(42);
}
function getDivisors(): Option<number[]> {
return Option.from([7, 3, 2]);
}
// We now could manually compose a function like this...
function wrappedDiv(n: number, ...divisors: number[]) {
const res = chainDivide(n, ...divisors);
if (
res === 0 ||Number.isNaN(res) || !Number.isFinite(res)
) return None;
return Some(res);
}
// ...or we could just use the `lift()` function with an appropriate ctor
const liftedDiv = Option.lift(chainDivide, Option.fromCoercible);
// If the ctor parameter is omitted, `Option.from()` is used per default
const liftedWithDefault = Option.lift(chainDivide);
const divident = getDivident();
const divisors = getDivisors();
const args = divident.zip(divisors);
const someWrapped = args.andThen(args => wrappedDiv(args[0], ...args[1]));
const someLifted = args.andThen(args => liftedDiv(args[0], ...args[1]));
assert(someWrapped.isSome() === true);
assert(someLifted.isSome() === true);
assert(someWrapped.unwrap() === someLifted.unwrap());