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
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; |
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
import { Lens } from "monocle-ts"; | |
interface Street { | |
num: number; | |
name: string; | |
} | |
interface Address { | |
city: string; | |
street: Street; | |
} |
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
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> |
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
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)), | |
} | |
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
// 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) |
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
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>> | |
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); |
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
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}`; |
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
Apply.ap( | |
Apply.ap( | |
Apply.map(effectWithFirstArgument, curriedTernaryFunction), | |
effectWithSecondArgument | |
), | |
effectWithThirdArgument | |
); |
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
// 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; |
NewerOlder