Skip to content

Instantly share code, notes, and snippets.

@mvaldesdeleon
Created August 10, 2018 17:00
Show Gist options
  • Save mvaldesdeleon/73e957dbe57d29f55ecfd0ae0fbb59fb to your computer and use it in GitHub Desktop.
Save mvaldesdeleon/73e957dbe57d29f55ecfd0ae0fbb59fb 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>;
}
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);
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);
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).getSum());
let p = Prod.of(1);
let q = Prod.of(2);
console.log(Prod.concat(p)(q).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 => 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());
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment