Published
Edited
Apr 28, 2021
1 fork
Insert cell
Insert cell
Insert cell
Result = ({
Ok: (data) => ({ type: 'Ok', data }),
Err: (data) => ({ type: 'Err', data })
})
Insert cell
Insert cell
function match(err, ok, variant) {
switch(variant.type) {
case 'Ok':
return ok(variant.data);
case 'Err':
return err(variant.data);
default:
return null;
}
}
Insert cell
Insert cell
{
const Val = ['hello'];

const Uppercase = (str) => [to_uppercase(str)];
const Exclaim = (str) => [exclaim(str)];

const one = Val.flatMap(Uppercase).flatMap(Exclaim);
const two = Val.flatMap(v => Uppercase(v).flatMap(Exclaim));
return [one.join(','), two.join(',')];
}
Insert cell
function to_uppercase(str) {
return str.toUpperCase();
}
Insert cell
function exclaim(str) {
return str + '!!';
}
Insert cell
Insert cell
function chain(ok, data) {
return match(Result.Err, ok, data);
}
Insert cell
Insert cell
chain_assoc_one = {
const Val = Result.Ok('hello');

const Uppercase = (str) => Result.Ok(to_uppercase(str));
const Exclaim = (str) => Result.Ok(exclaim(str));

return chain(Exclaim, chain(Uppercase, Val));
}
Insert cell
chain_assoc_two = {
const Val = Result.Ok('hello');

const Uppercase = (str) => Result.Ok(to_uppercase(str));
const Exclaim = (str) => Result.Ok(exclaim(str));

return chain(v => chain(Exclaim, Uppercase(v)), Val);
}
Insert cell
Insert cell
function unwrap(data) {
return match(Result.Err, value => value, data);
}
Insert cell
Insert cell
unwrap(chain_assoc_one) === unwrap(chain_assoc_two)
Insert cell
Insert cell
{
const Val = ['hello'];
const Id = Val.map(identity);
return [Val.join(', '), Id.join(', ')];
}
Insert cell
function identity(arg) {
return arg;
}
Insert cell
Insert cell
{
const Val = ['hello'];

const one = Val.map(v => exclaim(to_uppercase(v)));
const two = Val.map(to_uppercase).map(exclaim);
return [one.join(', '), two.join(', ')];
}
Insert cell
Insert cell
function map(fn, data){
return chain(v => Result.Ok(fn(v)), data);
}
Insert cell
Insert cell
functor_iden_one = {
return map(identity, Result.Ok('hello'));
}
Insert cell
functor_iden_two = {
return Result.Ok('hello');
}
Insert cell
unwrap(functor_iden_one) === unwrap(functor_iden_two);
Insert cell
Insert cell
functor_comp_one = {
const Val = Result.Ok('hello');
return map(v => exclaim(to_uppercase(v)), Val);
}
Insert cell
functor_comp_two = {
const Val = Result.Ok('hello');
return map(exclaim, map(to_uppercase, Val));
}
Insert cell
unwrap(functor_comp_one) === unwrap(functor_comp_two)
Insert cell
Insert cell
function ap(result, data) {
return chain(v => map(fn => fn(v), result), data);
}
Insert cell
Insert cell
apply_comp_one = {
const Val = Result.Ok('hello');

const composition = fx => gx => arg => fx(gx(arg));
const Uppercase = Result.Ok(to_uppercase);
const Exclaim = Result.Ok(exclaim);

return ap(ap(map(composition, Exclaim), Uppercase), Val);
}
Insert cell
apply_comp_two = {
const Val = Result.Ok('hello');

const Uppercase = Result.Ok(to_uppercase);
const Exclaim = Result.Ok(exclaim);

return ap(Exclaim, ap(Uppercase, Val));
}
Insert cell
unwrap(apply_comp_one) === unwrap(apply_comp_two);
Insert cell
Insert cell
{
const Title = Result.Ok('Dr. ');
const Name = Result.Ok('Acula');

const concat = (one, two) => one.concat(two);

return liftA2(concat, Title, Name);
}
Insert cell
Insert cell
function liftA2(fn, R1, R2) {
const curried = a => b => fn(a, b);
return ap(map(curried, R1), R2);
}
Insert cell
Insert cell
function liftA3(fn, R1, R2, R3) {
const curried = a => b => c => fn(a, b, c);
return ap(ap(map(curried, R1), R2), R3);
}
Insert cell
Insert cell
liftN = {
function curry(arity, fn, ...args) {
if(arity <= args.length) {
return fn(...args);
}

return curry.bind(null, arity, fn, ...args);
}

const apply = (arg, fn) => fn(arg);
const pipe = (fns) => (arg) => fns.reduce(apply, arg);

return function(fn, R1, ...RN) {
const arity = RN.length + 1;
const curried = curry(arity, fn);

const flipped = data => R => ap(R, data);
const _ap = pipe(RN.map(flipped));

return _ap(map(curried, R1));
}
}
Insert cell
Insert cell
{
const concat = (one, ...rest) => one.concat(...rest);

return liftN(
concat,
Result.Ok('Hello, '),
Result.Ok('Dr'),
Result.Ok('. '),
Result.Ok('Acula'),
Result.Ok('!!')
);
}
Insert cell
Insert cell
Promise.resolve('hello').then(to_uppercase);
Insert cell
Insert cell
(new Promise((resolve, reject) => { resolve('hello'); }))
.then(to_uppercase);
Insert cell
Insert cell
function of(value) {
return Result.Ok(value);
}
Insert cell
Insert cell
applicative_iden_one = {
return ap(of(identity), Result.Ok('hello'));
}
Insert cell
applicative_iden_two = {
return Result.Ok('hello');
}
Insert cell
unwrap(applicative_iden_one) === unwrap(applicative_iden_two);
Insert cell
Insert cell
applicative_hom_one = {
return ap(of(exclaim), of('hello'));
}
Insert cell
applicative_hom_two = {
return of(exclaim('hello'));
}
Insert cell
unwrap(applicative_hom_one) === unwrap(applicative_hom_two);
Insert cell
Insert cell
applicative_inter_one = {
const value = 'hello';
const Exclaim = of(exclaim);

return ap(Exclaim, of(value));
}
Insert cell
applicative_inter_two = {
const value = 'hello';
const Exclaim = Result.Ok(exclaim);

return ap(of(fn => fn(value)), Exclaim);
}
Insert cell
unwrap(applicative_inter_one) === unwrap(applicative_inter_two);
Insert cell
Insert cell
monad_li_one = {
return chain(exclaim, of('hello'));
}
Insert cell
monad_li_two = {
return exclaim('hello');
}
Insert cell
monad_li_one === monad_li_two;
Insert cell
Insert cell
function get_config() {
const config = fakeLocalStorage.getItem('config');

return config
? Result.Ok(config)
: Result.Err({ message: 'Config not found' });
}
Insert cell
Insert cell
Insert cell
Insert cell
function safe_parse(data) {
try {
return Result.Ok(JSON.parse(data));
} catch(e) {
return Result.Err(e);
}
}
Insert cell
Insert cell
map(safe_parse, get_config());
Insert cell
Insert cell
of('{"dark-mode":true}');
Insert cell
Insert cell
{
const one = chain(identity, of('{"dark-mode":true}'));
const two = identity('{"dark-mode":true}');
return [one, two];
}
Insert cell
Insert cell
function join(data) {
return match(Result.Err, identity, data);
}
Insert cell
Insert cell
join(map(safe_parse, get_config()));
Insert cell
Insert cell
chain(safe_parse, get_config());
Insert cell
Insert cell
monad_ri_one = {
return chain(of, Result.Ok('hello'));
}
Insert cell
monad_ri_two = {
return Result.Ok('hello');
}
Insert cell
unwrap(monad_ri_one) === unwrap(monad_ri_two);
Insert cell
Insert cell
function simpler_map(fn, data){
return chain(v => of(fn(v)), data);
}
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more