Skip to content

Instantly share code, notes, and snippets.

@ENvironmentSet
Last active October 24, 2019 12:44
Show Gist options
  • Save ENvironmentSet/ea1b2ec794dabb8f330e2698df1102e0 to your computer and use it in GitHub Desktop.
Save ENvironmentSet/ea1b2ec794dabb8f330e2698df1102e0 to your computer and use it in GitHub Desktop.
ClassAsADTDefinition
/**
data List a = Nil | Cons a (List a)
class Monoid a where
mempty :: a
mappend :: a -> a -> a
instance Monoid (List a) where
mempty = Nil
mappend Nil ys = ys
mappend xs Nil = xs
mappend (Cons x xs) ys = Cons x $ mappend xs ys
**/
abstract class Monoid<A> { // Type Class Monoid
public abstract getMempty(): A; // Required operations
public abstract mappend(x: A, y: A): A;
public static getMempty<A extends Monoid<A>>(instance: A): Monoid<A> { // Generalized operations
return instance.getMempty();
}
public static mappend<A>(instance: Monoid<A>, x: A, y: A): A;
public static mappend<A extends Monoid<A>>(instance: A, y: A): Monoid<A>;
public static mappend<A, B extends Monoid<B>>(instance: Monoid<A> | B, y: A | B, z?: A): A | Monoid<B> {
if (typeof z === 'undefined') return (instance as B).mappend(instance as B, y as B);
else return (instance as Monoid<A>).mappend(y as A, z);
}
}
abstract class List<A> extends Monoid<List<A>> {
public getMempty<A>(): Nil<A> {
return new Nil;
}
public mappend(xs: List<A>, ys: List<A>): List<A> {
if (xs instanceof Cons) return new Cons(xs.value, Monoid.mappend(xs.next, ys));
return ys;
}
}
class Nil<A> extends List<A> {}
class Cons<A> extends List<A> {
public constructor(public readonly value: A, public readonly next: List<A>) {
super();
}
}
const Add: Monoid<number> = {
getMempty(): number {
return 0;
},
mappend(x: number, y: number): number {
return x + y;
}
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment