Skip to content

Instantly share code, notes, and snippets.

@morozovamv
Last active April 24, 2019 06:30
Show Gist options
  • Save morozovamv/0d46bdff5dffc5fdf7c6b0784c52c156 to your computer and use it in GitHub Desktop.
Save morozovamv/0d46bdff5dffc5fdf7c6b0784c52c156 to your computer and use it in GitHub Desktop.
Road to monad: apply
import { Option, some, none, option } from "fp-ts/lib/Option";
import { liftA4 } from 'fp-ts/lib/Apply';
import { Function1 } from 'fp-ts/lib/function';
// Task: find the total age of two users
type TPerson = {
name: string;
// age: number;
age: Option<number>;
// age: Either<Error, number>;
};
const data: Array<TPerson> = [
{ name: 'Oleg', age: some(43) },
{ name: 'Denis', age: none },
];
const sum = (x: number) => (y: number): number => x + y;
const getPersonAgesSum = (data: Array<TPerson>): Option<number> => {
// const getPersonAgesSum = (data: Array<TPerson>): Option<number> => {
// const getPersonAgesSum = (data: Array<TPerson>): Either<Error, number> => {
const x = data[0].age; // Option<number> { value: 43, tag: 'some' }
const y = data[1].age; // { tag: 'none' }
// return sum(x)(y);
// const result = x.map(x => {
// return y.map(y => {
// return sum(x)(y);
// });
// });
// return result;
const fOpt = x.map(x => sum(x)); // Option<a -> b>
// if (fOpt.isSome() && y.isSome()) {
// return some(fOpt.value(y.value));
// }
// return none;
// const ap = <A, B>(f: Option<Function1<A, B>>, v: Option<A>): Option<B> => {
// if (f.isSome() && v.isSome()) {
// return some(f.value(v.value));
// }
// return none;
// }
// return ap(fOpt, y); // Option<number>
return y.ap(fOpt);
};
const result = getPersonAgesSum(data);
console.log('result', result);
// Lift
const sum4 = (x: number) => (y: number) => (z: number) => (w: number): number => x + y + z + w;
const x1 = some(1);
const sumRes = x1.ap(x1.ap(x1.ap(x1.map(sum4))));
// const liftA4 => context => f => a => b => x => y => y.ap(x.ap(b.ap(a.map(f))));
const sumRes2 = liftA4(option)(sum4)(x1)(x1)(x1)(x1);
console.log('sumRes: ', sumRes, 'sumRes2: ', sumRes2);
const result4 = liftA4(option)(sum4)(x1)(x1)(none)(x1);
console.log('result4', result4);
// Rules
const identity = <A>(v: A): A => v;
const compose = <A, B, C>(f: Function1<B, C>) => (g: Function1<A, B>) => (x: A): C => f(g(x));
const f = (n: number): string => `${n}`;
const g = (n: number): number => n + 2;
// Identity law
const Id = x1.ap(some(identity));
console.log('Id', Id);
// Composition law
const C1 = x1.ap(some(g).ap(some(f).map(f => compose(f))));
const C2 = x1.ap(some(g)).ap(some(f));
console.log('C1', C1);
console.log('C2', C2);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment