Skip to content

Instantly share code, notes, and snippets.

@zaetrik
zaetrik / compose.ts
Created June 4, 2020 12:59
Compose Functions
const composeLeftToRight = <F extends (x: any) => any>(...fns: Array<F>) => (
...[x]: Parameters<F>
): ReturnType<F> => fns.reduce((y, f) => f(y), x);
const composeRightToLeft = <F extends (x: any) => any>(...fns: Array<F>) => (
...[x]: Parameters<F>
): ReturnType<F> => fns.reduceRight((y, f) => f(y), x);
const addTwo = (x: number) => x + 2;
@zaetrik
zaetrik / monocle-ts-compose-modifiers.ts
Last active June 4, 2020 18:19
monocle-ts composing modifiers
import { Lens } from "monocle-ts";
interface Street {
num: number;
name: string;
}
interface Address {
city: string;
street: Street;
}
@zaetrik
zaetrik / monads-example.ts
Created May 12, 2020 07:54
Monads: Example
import * as O from "fp-ts/lib/Option";
const addTwo = (x: number) => some(x + 2);
// Now we can work with nested contexts, thanks to chain/flatMap in our Monad instance
O.chain(addTwo)(O.some(5)); // => Option<number>
@zaetrik
zaetrik / monads-flatmap-chain.ts
Last active May 12, 2020 08:38
Monads: flatMap & chain
interface Monad<M> extends Applicative<M> {
flatMap: <A, B>(f: (a: A) => M<B>) => ((ma: M<A>) => M<B>);
}
// An implementation could look like this
const OptionMonad = {
...OptionApplicative,
flatMap: (f) => (ma) => (isNone(ma) ? none : f(ma.value)),
}
@zaetrik
zaetrik / monads-flatten.ts
Created May 12, 2020 07:23
Monads: Flatten
// Taken from https://dev.to/gcanti/getting-started-with-fp-ts-monad-6k
import { isNone } from 'fp-ts/lib/Option'
// flatten takes in a nested context like Option<Option<A>> and flattens/unwraps it to Option<A>
// We do this by returning the value from the nested context Option<Option<A>> which is Option<A>
const flatten = <A>(mma: Option<Option<A>>): Option<A> => (isNone(mma) ? none : mma.value)
@zaetrik
zaetrik / monads-nested-contexts.ts
Created May 12, 2020 07:20
Monads: Nested Contexts
import * as O from "fp-ts/lib/Option";
addTwo :: number -> Option<number>
const addTwo = (x: number) => O.some(x + 2);
// If we map() with addTwo we get a nested context
O.map(addTwo, O.some(5)) // => Option<Option<number>>
@zaetrik
zaetrik / composing-pure-nary-effectful.ts
Created May 10, 2020 08:13
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);
@zaetrik
zaetrik / composing-pure-effectful.ts
Created May 9, 2020 16:24
Functor: Compose a pure function with an effectful function
import { Option, isNone, none, some } from "fp-ts/lib/Option";
// Here we lift a pure function to work with Option
// Taken from https://dev.to/gcanti/getting-started-with-fp-ts-functor-36ek
function lift<A, B>(f: (a: A) => B): (fa: Option<A>) => Option<B> {
return (fa) => (isNone(fa) ? none : some(f(fa.value)));
}
const effectfulDouble = (x: number) => some(x * 2);
const pureSay = (x: number) => `The result is ${x}`;
@zaetrik
zaetrik / ap-ternary-function.ts
Created May 9, 2020 13:44
Apply ap() with a ternary function
Apply.ap(
Apply.ap(
Apply.map(effectWithFirstArgument, curriedTernaryFunction),
effectWithSecondArgument
),
effectWithThirdArgument
);
@zaetrik
zaetrik / applicative-of-example.ts
Last active May 9, 2020 09:11
Applicative of() example
// This is how fp-ts implements this for Option
// Taken from https://github.com/gcanti/fp-ts/blob/master/src/Option.ts
interface None {
readonly _tag: "None";
}
interface Some<A> {
readonly _tag: "Some";
readonly value: A;