Skip to content

Commit

Permalink
feat: Enforce Functor
Browse files Browse the repository at this point in the history
  • Loading branch information
MikuroXina committed Aug 1, 2022
1 parent 45c12de commit 72ba4e8
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 0 deletions.
5 changes: 5 additions & 0 deletions src/hkt.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
export interface Hkt<Symbol extends symbol, A> {
_symbol: Symbol;
_args: A;
}

export interface HktDictA1<A1> {}
export interface HktDictA2<A1, A2> extends HktDictA1<A1> {}
export interface HktDictA3<A1, A2, A3> extends HktDictA2<A1, A2> {}
Expand Down
23 changes: 23 additions & 0 deletions src/type-class/functor.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import type {
Hkt,
HktA1,
HktA2,
HktA3,
Expand All @@ -9,6 +10,9 @@ import type {
HktDictA4,
} from "../hkt";

export interface Functor<F extends symbol> {
map<T, U>(fn: (t: T) => U): (t: Hkt<F, T>) => Hkt<F, U>;
}
export interface Functor1<A extends HktA1> {
map<T1, U1>(fn: (t: T1) => U1): (t: HktDictA1<T1>[A]) => HktDictA1<U1>[A];
}
Expand All @@ -25,3 +29,22 @@ export interface Functor4<A extends HktA4> {
fn: (t: T1) => U1,
): (t: HktDictA4<T1, T2, T3, T4>[A]) => HktDictA4<U1, T2, T3, T4>[A];
}

export const map =
<SymbolA extends symbol, SymbolB extends symbol>(
funcA: Functor<SymbolA>,
funcB: Functor<SymbolB>,
) =>
<T, U>(f: (t: T) => U) =>
(funcT: Hkt<SymbolA, Hkt<SymbolB, T>>) =>
funcA.map(funcB.map(f))(funcT);

export const flap =
<Symbol extends symbol>(func: Functor<Symbol>) =>
<T, U>(t: T) =>
func.map((f: (t: T) => U) => f(t));

export const bindTo =
<Symbol extends symbol>(func: Functor<Symbol>) =>
<N extends keyof any>(name: N) =>
func.map(<T>(a: T) => ({ [name]: a } as Record<N, T>));

0 comments on commit 72ba4e8

Please sign in to comment.