Skip to content

Instantly share code, notes, and snippets.

@morozovamv
Created December 10, 2018 14:32
Show Gist options
  • Save morozovamv/0dcb0bc83fda35cd30ae5fb2e6e57e17 to your computer and use it in GitHub Desktop.
Save morozovamv/0dcb0bc83fda35cd30ae5fb2e6e57e17 to your computer and use it in GitHub Desktop.
Road to monad: final
import { some, Option, none, getSetoid, option } from 'fp-ts/lib/Option';
import { setoidNumber } from 'fp-ts/lib/Setoid';
import { liftA2 } from 'fp-ts/lib/Apply';
const isEquals = (x: Option<number>, y: Option<number>) => getSetoid(setoidNumber).equals(x, y);
// Monad = Applicative & Chain + Laws
// Laws:
// 1. Left identity: M.chain(M.of(a), f) = f(a)
// 2. Right identity: M.chain(fa, M.of) = fa
//
// M - monad typeclass
// a - any type
// f - function: (value: A) => M<B>
// M = Option
// a
const value = 1;
// f
const inc = (v: number): Option<number> => (v > 99 ? some(v + 1) : none);
// Left identity example
const xLID = some(value).chain(inc);
const yLID = inc(value);
const isEqualLID = isEquals(xLID, yLID);
// Right identity example
const xRID = some(value).chain(some);
const yRID = some(value);
const isEqualRID = isEquals(xRID, yRID);
console.log('Left identity', isEqualLID);
console.log('Right identity', isEqualRID);
type TUser = {
id: number;
age: number;
name: string;
};
const x = some(4);
const data: Option<TUser> = some({ id: 0, age: 12, name: 'sasha' });
// map - how to change value inside context? | M<A>.map(A -> B) -> M<B>
data.map(v => v.age);
// ap - how to apply function in context to value in context? | M<A>.ap(M<A -> B>) -> M<B>
const f = (n: number): number => n + 2;
some(4).ap(some(f));
const p = (user: TUser) => (additional: number) => user.age + additional;
x.ap(data.map(v => p(v))) === liftA2(option)(p)(data)(x); // true
// of - how to lift value to context? | M.of(A) -> M<A>
some(4);
// chain - function composition | M<A>.chain(A -> M<B>) -> M<B>
declare const g: (x: number) => Option<string>;
declare const i: (x: string) => Option<{ id: string }>;
declare const k: (x: { id: string }) => Option<number>;
g(4)
.chain(str => i(str))
.chain(obj => k(obj));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment