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

One platform to build and deploy the best data apps

Experiment and prototype by building visualizations in live JavaScript notebooks. Collaborate with your team and decide which concepts to build out.
Use Observable Framework to build data apps locally. Use data loaders to build in any language or library, including Python, SQL, and R.
Seamlessly deploy to Observable. Test before you ship, use automatic deploy-on-commit, and ensure your projects are always up-to-date.
Learn more