Skip to content

Commit

Permalink
feat: Add monoidal categories (#52)
Browse files Browse the repository at this point in the history
  • Loading branch information
MikuroXina authored Feb 28, 2023
1 parent 5a5b574 commit 5f927fb
Show file tree
Hide file tree
Showing 19 changed files with 520 additions and 7 deletions.
44 changes: 44 additions & 0 deletions src/dual.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import type { FnHkt } from "./func.js";
import type { Get2, Hkt2 } from "./hkt.js";
import type { GenericBifunctor } from "./type-class/bifunctor.js";
import type { Category } from "./type-class/category.js";
import type { Monoid } from "./type-class/monoid.js";
import type { Contravariant } from "./type-class/variance.js";

export interface Dual<A, B> {
(b: B): A;
}

export interface DualHkt extends Hkt2 {
readonly type: Dual<this["arg2"], this["arg1"]>;
}

export const cat: Category<DualHkt> = {
identity: () => (x) => x,
compose: (funcA) => (funcB) => (c) => funcB(funcA(c)),
};

export const contra: Contravariant<DualHkt> = {
contraMap:
<T, U>(f: (t: T) => U) =>
<A>(bDual: Dual<A, U>): Dual<A, T> =>
(t) =>
bDual(f(t)),
};

export const monoid = <A, B>(m: Monoid<A>): Monoid<Dual<A, B>> => ({
identity: () => m.identity,
combine: (f, g) => (b) => m.combine(f(b), g(b)),
});

export const bifunctor = <T>(
bf: GenericBifunctor<FnHkt, FnHkt, FnHkt, T>,
): GenericBifunctor<DualHkt, DualHkt, DualHkt, T> => ({
cat1: cat,
cat2: cat,
cat3: cat,
genericBiMap:
<A, B>(f: Dual<A, B>) =>
<C, D>(g: Dual<C, D>): Dual<Get2<T, A, C>, Get2<T, B, D>> =>
bf.genericBiMap(f)(g),
});
6 changes: 6 additions & 0 deletions src/lib.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ export * as Cont from "./cont.js";
export * as MonadCont from "./cont/monad.js";
export * as Coyoneda from "./coyoneda.js";
export * as Curry from "./curry.js";
export * as Dual from "./dual.js";
export * as Free from "./free.js";
export * as MonadFree from "./free/monad.js";
export * as Frozen from "./frozen.js";
Expand All @@ -19,14 +20,19 @@ export * as List from "./list.js";
export * as Number from "./number.js";
export * as Option from "./option.js";
export * as Ordering from "./ordering.js";
export * as Predicate from "./predicate.js";
export * as Promise from "./promise.js";
export * as MonadPromise from "./promise/monad.js";
export * as Reader from "./reader.js";
export * as MonadReader from "./reader/monad.js";
export * as Result from "./result.js";
export * as Seq from "./seq.js";
export * as Star from "./star.js";
export * as State from "./state.js";
export * as StateMonad from "./state/monad.js";
export * as Store from "./store.js";
export * as String from "./string.js";
export * as These from "./these.js";
export * as Trans from "./trans.js";
export * as TupleN from "./tuple-n.js";
export * as Tuple from "./tuple.js";
Expand Down
20 changes: 20 additions & 0 deletions src/predicate.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import type { Hkt1 } from "./hkt.js";
import type { Monoid } from "./type-class/monoid.js";
import type { Contravariant } from "./type-class/variance.js";

export interface Predicate<A> {
(a: A): boolean;
}

export interface PredicateHkt extends Hkt1 {
readonly type: Predicate<this["arg1"]>;
}

export const contra: Contravariant<PredicateHkt> = {
contraMap: (mapper) => (predB) => (a) => predB(mapper(a)),
};

export const monoid = <A>(): Monoid<Predicate<A>> => ({
identity: () => true,
combine: (predL, predR) => (a) => predL(a) && predR(a),
});
17 changes: 17 additions & 0 deletions src/star.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import type { Apply3Only, Get1, Hkt1, Hkt3 } from "./hkt.js";
import type { Functor } from "./type-class/functor.js";
import { Profunctor, rightMap } from "./type-class/profunctor.js";

export interface Star<F, D, C> {
(d: D): Get1<F, C>;
}

export interface StarHkt extends Hkt3 {
readonly type: Star<this["arg3"], this["arg2"], this["arg1"]>;
}

export const pro = <F extends Hkt1>(functor: Functor<F>): Profunctor<Apply3Only<StarHkt, F>> => ({
diMap: (f) => (g) => (m) => (d) => functor.map(g)(m(f(d))),
});

export const map = <F extends Hkt1>(functor: Functor<F>) => rightMap(pro(functor));
Loading

0 comments on commit 5f927fb

Please sign in to comment.