Created
May 10, 2020 08:13
-
-
Save zaetrik/47115ea6453c32742559552311446fab to your computer and use it in GitHub Desktop.
Applicative: Compose pure n-ary functions with effectful functions
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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