Last active
April 24, 2019 06:30
-
-
Save morozovamv/0d46bdff5dffc5fdf7c6b0784c52c156 to your computer and use it in GitHub Desktop.
Road to monad: apply
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, 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