Skip to content

Instantly share code, notes, and snippets.

@Voltra
Created July 5, 2022 20:43
Show Gist options
  • Select an option

  • Save Voltra/ac2f639c5d43efdc8c71899cb5e2015c to your computer and use it in GitHub Desktop.

Select an option

Save Voltra/ac2f639c5d43efdc8c71899cb5e2015c to your computer and use it in GitHub Desktop.
fp.ts
export interface Semigroup<T, Self> {
concat(b: Semigroup<T, Self>): Semigroup<T, Self>;
sconcat(b: Semigroup<T, Self>): Semigroup<T, Self>;
stimes(n: number): Semigroup<T, Self>;
}
const decorateSemigroup = <T, Self>(sg: Partial<Semigroup<T, Self>>): Semigroup<T, Self> => {
sg.stimes = function(this: Semigroup<T, Self>, n: number): Semigroup<T, Self> {
let ret = this;
for (let i = 0 ; i < n ; ++i) {
ret = this.concat(ret);
}
return ret;
};
sg.sconcat = sg.concat;
return sg as Semigroup<T, Self>;
};
export interface Monoid<T, Self> extends Semigroup<T, Self> {
mempty(): Monoid<T, Self>;
mappend(b: Monoid<T, Self>): Monoid<T, Self>;
mconcat(ts: Monoid<T, Self>[]): Monoid<T, Self>;
}
const decorateMonoid = <T, Self>(monoid: Partial<Monoid<T, Self>>): Monoid<T, Self> => {
monoid.mappend = monoid.concat as (b: Monoid<T, Self>) => Monoid<T, Self>;
monoid.mconcat = function(this: Monoid<T, Self>, ts: Monoid<T, Self>[]): Monoid<T, Self> {
return [this, ...ts].reduceRight((a, b) => a.mappend(b), this.mempty());
};
return monoid as Monoid<T, Self>;
};
export interface Foldable<T, Self> {
foldMap<U, USelf>(f: (a: T) => Monoid<T, Self>): Monoid<T, Self>;
foldr<U, USelf>(f: (a: T, b: U) => U, u: U): U;
toList(): Array<T>;
}
export const decorateFoldable = <T, Self>(foldable: Partial<Foldable<T, Self>>): Foldable<T, Self> => {
foldable.toList = function(this: Foldable<T, Self>) {
return this.foldr<Array<T>, Self>((item: T, arr: Array<T>) => [item].concat(arr as any as T[]) as any as Array<T>, [] as any as Array<T>);
};
return foldable as Foldable<T, Self>;
};
export interface Functor<T, Self> {
map<U, USelf>(f: (t: T) => U): Functor<U, USelf>;
fill<U, USelf>(a: U): Functor<U, USelf>;
}
export const decorateFunctor = <T, Self>(functor: Partial<Functor<T, Self>>): Functor<T, Self> => {
functor.fill = function<U, USelf>(this: Functor<T, Self>, a: U): Functor<U, USelf> {
return this.map(() => a);
};
return functor as Functor<T, Self>;
};
export interface Monad<T, Self> extends Functor<T, Self> {
flatMap<U, USelf>(f: (t: T) => Monad<U, USelf>): Monad<U, USelf>;
return_(t: T): Monad<T, Self>;
}
export interface Applicative<T, Self> extends Functor<T, Self> {
pure(t: T): Applicative<T, Self>;
applySeq<FSelf, U, USelf>(f: Applicative<(t: T) => U, FSelf>, b: Applicative<U, USelf>): Applicative<U, USelf>;
liftA2<U, USelf, V, VSelf>(f: (t: T, u: U) => V, b: Applicative<U, USelf>): Applicative<V, VSelf>;
applySeqR<U, USelf>(b: Applicative<U, USelf>): Applicative<U, USelf>;
applySeqL<U, USelf>(b: Applicative<U, USelf>): Applicative<T, Self>;
}
export interface Array<T> extends Monad<T, Array<T>> {
map<U>(f: (t: T) => U): Array<U>;
flatMap<U>(f: (t: T) => Array<U>): Array<U>;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment