Skip to main content
Module

x/eitherway/mod.ts>Option.lift

Yet Another Option and Result Implementation - providing safe abstractions for fallible flows inspired by F# and Rust
Latest
function Option.lift
import { Option } from "https://deno.land/x/eitherway@0.10.0/mod.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

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());

Type Parameters

Args extends Readonly<unknown[]>
R1
optional
R2 = NonNullish<R1>

Parameters

fn: (...args: Args) => R1
optional
ctor: (arg: R1) => Option<R2> = [UNSUPPORTED]