Skip to content

Instantly share code, notes, and snippets.

@moonformeli
Last active July 19, 2020 07:36
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save moonformeli/801affc6339c6dc83a4fe42620ad457c to your computer and use it in GitHub Desktop.
Save moonformeli/801affc6339c6dc83a4fe42620ad457c to your computer and use it in GitHub Desktop.
function assertNumber(x: any): asserts x is number {
if (typeof x !== 'number') {
throw new Error('x has to be a number type');
}
}
function assertTrue(b: boolean): asserts b is true {
if (typeof b !== 'boolean') {
throw new Error('must be a boolean type');
}
if (b !== true) {
throw new Error('must be true');
}
}
class Monoid<T extends number> {
constructor(private s: T[]) { }
concat(x: T, y: T): T {
return (x + y) as T;
}
identity(x: T): T {
return x + 0;
}
pick(count: T): T[] {
const items: T[] = [];
while (items.length < count) {
const randomIndex = Math.trunc(Math.random() * (this.s.length - 1));
const randomItem = this.s[randomIndex];
if (!items.includes(randomItem)) {
items.push(randomItem);
}
}
return items;
}
}
const set = new Monoid([1, 2, 3, 4, 5]);
// Magma
const [a, b] = set.pick(2);
assertNumber(a);
assertNumber(b);
assertNumber(a + b);
// Semigroup - Associativity
const [x, y, z] = set.pick(3);
assertNumber(set.concat(set.concat(x, y), z));
assertNumber(set.concat(x, set.concat(y, z)));
assertTrue(set.concat(set.concat(x, y), z) === set.concat(x, set.concat(y, z)));
// Monoid - Identity
const [r] = set.pick(1);
assertNumber(r);
assertNumber(set.identity(r));
assertTrue(set.identity(r) === r);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment