Skip to content

Instantly share code, notes, and snippets.

@mvaldesdeleon
Created August 10, 2018 18:10
Show Gist options
  • Select an option

  • Save mvaldesdeleon/017abf7fa16d71f447a858faa64c9ed4 to your computer and use it in GitHub Desktop.

Select an option

Save mvaldesdeleon/017abf7fa16d71f447a858faa64c9ed4 to your computer and use it in GitHub Desktop.
interface MonoidCtor<A> {
new (a: any): Monoid<A>;
of (value: any): Monoid<A>;
empty (): Monoid<A>;
concat: (a: Monoid<A>) => (b: Monoid<A>) => Monoid<A>;
reify: (a: Monoid<A>) => A;
}
interface Monoid<A> {
empty: () => A;
concat: (a: A) => A;
}
class Sum implements Monoid<Sum> {
public static of(value: number) {
return new Sum(value);
}
public static empty() {
return new Sum(0);
}
public static concat = (a: Sum) => (b: Sum) => Sum.of(a.value + b.value);
public static reify = (a: Monoid<Sum>) => a as Sum;
constructor(private value: number) {}
empty() {
return Sum.empty();
}
concat(a: Sum) {
return Sum.concat (this) (a);
}
getSum() {
return this.value;
}
}
class Prod implements Monoid<Prod> {
public static of(value: number) {
return new Prod(value);
}
public static empty() {
return new Prod(1);
}
public static concat = (a: Prod) => (b: Prod) => Prod.of(a.value * b.value);
public static reify = (a: Monoid<Prod>) => a as Prod;
constructor(private value: number) {}
empty() {
return Prod.empty();
}
concat(a: Prod) {
return Prod.concat (this) (a);
}
getProd() {
return this.value;
}
}
let s = Sum.of(1);
let t = Sum.of(2);
console.log(Sum.concat(s)(t).concat(Sum.empty()).concat(t.empty()).getSum());
let p = Prod.of(1);
let q = Prod.of(2);
console.log(Prod.concat(p)(q).concat(Prod.empty()).concat(q.empty()).getProd());
console.log( [1,2,3,4].reduce ((p, v) => p.concat(Prod.of(v)), Prod.empty()) );
console.log( [1,2,3,4].reduce ((p, v) => p.concat(Sum.of(v)), Sum.empty()) );
const foldMap = <A>(typeRep: MonoidCtor<A>, xs: any[]): A => typeRep.reify(xs.reduce((m, x) => m.concat(typeRep.of(x)), typeRep.empty()));
let a = foldMap(Sum, [1,2,3,4]);
let b = foldMap(Prod, [1,2,3,4]);
console.log(a.getSum());
console.log(a.getProd());
//const concat = <A>(typeRep: MonoidCtor<A>, lhs: Monoid<A>, rhs: Monoid<A>): A => typeRep.reify(typeRep.concat(lhs)(rhs));
const concat = <A>(lhs: Monoid<A>, rhs: Monoid<A>): A => (lhs.constructor as MonoidCtor<A>).reify((lhs.constructor as MonoidCtor<A>).concat(lhs)(rhs));
// let c = concat(Sum, s, t);
// let d = concat(Prod, s, t);
// let e = concat(Sum, s, q);
let c = concat(s, t);
let d = concat(s, t);
let e = concat(s, q);
console.log(c.getSum());
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment