Skip to content

Instantly share code, notes, and snippets.

@zaetrik
Created May 10, 2020 08:13
Show Gist options
  • Save zaetrik/47115ea6453c32742559552311446fab to your computer and use it in GitHub Desktop.
Save zaetrik/47115ea6453c32742559552311446fab to your computer and use it in GitHub Desktop.
Applicative: Compose pure n-ary functions with effectful functions
// We import the the Option effect from fp-ts
// We could also implement our own Applicative instance
import * as O from "fp-ts/lib/Option";
// lift function for the Option effect for pure functions with arity 2
function liftA2<A, B, C>(f: (a: A) => (b: B) => C): (a: O.Option<A>) => (b: O.Option<B>) => O.Option<C> {
return (fa) => (fb) => (O.isNone(fa) || O.isNone(fb) ? O.none : O.ap(fb)(O.map(f)(fa)));
}
const effectfulDouble = (x: number) => O.some(x * 2);
// Binary pure function
const pureBinarySay = (text: string) => (x: number) => `${text} ${x}`;
// We lift pureBinarySay to a function of type:
// (text: O.Option<string>) => (x: O.Option<number>) => O.Option<string>
const liftedPureBinarySay = liftA2(pureBinarySay);
liftedPureBinarySay(O.some("The result is"))(effectfulDouble(5)); // { _tag: 'Some', value: 'The result is 10' }
// We can do the same for pure ternary functions
// lift function for the Option effect for pure functions with arity 3
function liftA3<A, B, C, D>(
f: (a: A) => (b: B) => (c: C) => D
): (a: O.Option<A>) => (b: O.Option<B>) => (c: O.Option<C>) => O.Option<D> {
return (fa) => (fb) => (fc) =>
O.isNone(fa) || O.isNone(fb) || O.isNone(fc) ? O.none : O.ap(fc)(O.ap(fb)(O.map(f)(fa)));
}
// Ternary pure function
const add = (x: number) => (y: number) => (z: number) => x + y + z;
// We lift add to a function of type:
// (x: O.Option<number>) => (y: O.Option<number>) => (z: O.Option<number>) => O.Option<number>
const addLifted = liftA3(add);
addLifted(effectfulDouble(2))(effectfulDouble(5))(O.some(10)); // { _tag: 'Some', value: 24 }
// We could now create lift functions for any arity
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment