Skip to content

Commit

Permalink
fix: Fix to use void over unit (#107)
Browse files Browse the repository at this point in the history
  • Loading branch information
MikuroXina authored Sep 20, 2023
1 parent 0219c9e commit f7efc73
Show file tree
Hide file tree
Showing 11 changed files with 42 additions and 40 deletions.
6 changes: 3 additions & 3 deletions src/array.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import type { Monad } from "./type-class/monad.js";
import type { Reduce } from "./type-class/reduce.js";

export interface ArrayHkt extends Hkt1 {
readonly type: this["arg1"][];
readonly type: readonly this["arg1"][];
}

export const functor: Functor<ArrayHkt> = {
Expand All @@ -27,8 +27,8 @@ export const monad: Monad<ArrayHkt> = {
*/
export const fromReduce =
<F>(reduce: Reduce<F>) =>
<A>(fa: Get1<F, A>): readonly A[] =>
reduce.reduceL((arr: readonly A[]) => (elem: A) => [...arr, elem])([])(fa);
<A>(fa: Get1<F, A>): ReadonlyArray<A> =>
reduce.reduceL((arr: A[]) => (elem: A) => [...arr, elem])([])(fa);

/**
* Reduces the elements of array by `reducer` from right-side.
Expand Down
6 changes: 3 additions & 3 deletions src/cat.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,12 +49,12 @@ export interface CatT<M, CTX> {
) => CatT<M, Record<K, A> & CTX>;

/**
* Runs the computation but discards its return value.
* Runs the computation and overwrites the context with its return value.
*
* @param computation - The computation to run.
* @returns A new `CatT` with modified environment.
*/
readonly then: (computation: Get1<M, CTX>) => CatT<M, CTX>;
readonly then: <T>(computation: Get1<M, T>) => CatT<M, T>;

/**
* Binds a new value wrapped by the monad, calculated from `ctx` by `fn`.
Expand Down Expand Up @@ -120,7 +120,7 @@ export const catT =
* @param monad - The monad implementation for `M`.
* @returns A new `CatT`.
*/
export const doVoidT = <M>(monad: Monad<M>): CatT<M, []> => catT(monad)(monad.pure([]));
export const doVoidT = <M>(monad: Monad<M>): CatT<M, void> => catT(monad)(monad.pure(undefined));

/**
* Creates a new `CatT` with an empty context.
Expand Down
6 changes: 3 additions & 3 deletions src/cont.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ test("with", () => {
});

test("simple usage", () => {
const calcLength = <A, R>(a: A[]): Cont<R, number> => pure(a.length);
const calcLength = <A, R>(a: readonly A[]): Cont<R, number> => pure(a.length);
const double = <R>(num: number): Cont<R, number> => pure(num * 2);
const callback = vitest.fn();
cat([1, 2, 3]).feed(calcLength).feed(flatMap(double)).feed(runContT).value(callback);
Expand All @@ -45,10 +45,10 @@ test("simple usage", () => {
test("using callCC", () => {
const validateName =
(name: string) =>
(exit: (a: string) => Cont<string, []>): Cont<string, []> =>
(exit: (a: string) => Cont<string, void>): Cont<string, void> =>
when(name.length === 0)(exit("expected at least 1 character"));
const whatYourName = (name: string): string => {
const cont = callCC<string, IdentityHkt, string, []>(
const cont = callCC<string, IdentityHkt, string, void>(
(exit) =>
cat(validateName(name)(exit)).feed(flatMap(() => pure(`Welcome, ${name}!`))).value,
);
Expand Down
10 changes: 5 additions & 5 deletions src/cont.ts
Original file line number Diff line number Diff line change
Expand Up @@ -254,8 +254,8 @@ export const liftPromise =
*/
export const when =
(cond: boolean) =>
<R>(cont: Cont<R, []>): Cont<R, []> =>
cond ? cont : pure([]);
<R>(cont: Cont<R, void>): Cont<R, void> =>
cond ? cont : pure(undefined);
/**
* Provides a branch statement for `Cont`. `cont` will be evaluated if `cond` is `false`, otherwise it will be an empty computation.
*
Expand All @@ -265,15 +265,15 @@ export const when =
*/
export const unless =
(cond: boolean) =>
<R>(cont: Cont<R, []>): Cont<R, []> =>
cond ? pure([]) : cont;
<R>(cont: Cont<R, void>): Cont<R, void> =>
cond ? pure(undefined) : cont;
/**
* Provides an assertion statement for `Cont`. It will returns an empty computation if `cond` is true, otherwise it will occur an exception.
*
* @param cond - The condition as branch statement.
* @returns The assertion computation.
*/
export const guard = <R>(cond: boolean): Cont<R, []> => (cond ? pure([]) : absurd);
export const guard = <R>(cond: boolean): Cont<R, void> => (cond ? pure(undefined) : absurd);

export interface ContHkt extends Hkt2 {
readonly type: Cont<this["arg2"], this["arg1"]>;
Expand Down
10 changes: 5 additions & 5 deletions src/free.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,11 +80,11 @@ describe("hello language", () => {
}
};

const hello: Free<HelloLangHkt, []> = liftF(functor)({ type: "Hello", next: [] });
const hey: Free<HelloLangHkt, []> = liftF(functor)({ type: "Hey", next: [] });
const yearsOld = (years: number): Free<HelloLangHkt, []> =>
liftF(functor)({ type: "YearsOld", years, next: [] });
const bye: Free<HelloLangHkt, []> = liftF(functor)({ type: "Bye" });
const hello: Free<HelloLangHkt, void> = liftF(functor)({ type: "Hello", next: undefined });
const hey: Free<HelloLangHkt, void> = liftF(functor)({ type: "Hey", next: undefined });
const yearsOld = (years: number): Free<HelloLangHkt, void> =>
liftF(functor)({ type: "YearsOld", years, next: undefined });
const bye: Free<HelloLangHkt, void> = liftF(functor)({ type: "Bye" });

const m = freeMonad(functor);

Expand Down
4 changes: 2 additions & 2 deletions src/option.ts
Original file line number Diff line number Diff line change
Expand Up @@ -519,5 +519,5 @@ export const traversable: Traversable<OptionHkt> = {

export const ifSome = <T, U>(): Optic<Option<T>, Option<U>, T, U> =>
newPrism<U, Option<U>>(some)(mapOrElse<Result<Option<U>, T>>(() => err(none()))(ok));
export const ifNone = <T>(): OpticSimple<Option<T>, []> =>
newPrismSimple<[], Option<T>>(none)(mapOrElse<Option<[]>>(() => some([]))(none));
export const ifNone = <T>(): OpticSimple<Option<T>, void> =>
newPrismSimple<void, Option<T>>(none)(mapOrElse<Option<void>>(() => some(undefined))(none));
4 changes: 2 additions & 2 deletions src/state.ts
Original file line number Diff line number Diff line change
Expand Up @@ -145,8 +145,8 @@ export const get =
* @returns The computation which sets the new state.
*/
export const put =
<S>(state: S): State<S, []> =>
() => [[], state];
<S>(state: S): State<S, void> =>
() => [undefined, state];

/**
* Makes two computations into a product about the result type.
Expand Down
8 changes: 4 additions & 4 deletions src/state/monad.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,13 @@ export interface MonadState<S, M> extends Monad<M> {
export const get = <S, M>(s: MonadState<S, M>): Get1<M, S> => s.state((state) => [state, state]);
export const set =
<S, M>(s: MonadState<S, M>) =>
(state: S): Get1<M, []> =>
s.state(() => [[], state]);
(state: S): Get1<M, void> =>
s.state(() => [undefined, state]);

export const modify =
<S, M>(s: MonadState<S, M>) =>
(modifier: (state: S) => S): Get1<M, []> =>
s.state((state) => [[], modifier(state)]);
(modifier: (state: S) => S): Get1<M, void> =>
s.state((state) => [undefined, modifier(state)]);
export const gets =
<S, M>(s: MonadState<S, M>) =>
<A>(f: (state: S) => A): Get1<M, A> =>
Expand Down
16 changes: 9 additions & 7 deletions src/writer.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { expect, test } from "vitest";

import { cat } from "./cat.js";
import { cat, doVoidT } from "./cat.js";
import type { Monoid } from "./type-class/monoid.js";
import { semiGroupSymbol } from "./type-class/semi-group.js";
import {
Expand All @@ -9,6 +9,7 @@ import {
executeWriter,
flatMap,
listen,
makeMonad,
map,
pure,
tell,
Expand All @@ -29,9 +30,9 @@ test("tell with tower of hanoi", () => {
from: string,
to: string,
another: string,
): Writer<[string, string][], []> => {
): Writer<[string, string][], void> => {
if (height < 1) {
return pure(monoid)([]);
return pure(monoid)(undefined);
}
if (height === 1) {
return tell([[from, to]]);
Expand Down Expand Up @@ -85,12 +86,13 @@ test("listen with collatz sequence", () => {
});

test("censor with log decoration", () => {
const monoid = monoidArray<string>();
const m = makeMonad(monoidArray<string>());

const hello = (): Writer<string[], []> =>
cat(tell(["Hello!"])).feed(flatMap(monoid)(() => tell(["What do you do?"]))).value;
const hello = doVoidT(m)
.then(tell(["Hello!"]))
.then(tell(["What do you do?"])).ctx;
const log = censor((messages: string[]) => messages.map((message) => `[LOG] ${message}`))(
hello(),
hello,
);
expect(executeWriter(log)).toEqual(["[LOG] Hello!", "[LOG] What do you do?"]);
});
8 changes: 4 additions & 4 deletions src/writer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,9 @@ export const mapWriterT =
*/
export const tellM =
<M>(monad: Monad<M>) =>
<W>(w: W): WriterT<W, M, []> =>
<W>(w: W): WriterT<W, M, void> =>
() =>
monad.pure([[], w]);
monad.pure([undefined, w]);
/**
* Creates an action that executes `writer` and adds its output to the value of the computation.
*
Expand Down Expand Up @@ -142,8 +142,8 @@ export const mapWriter =
* @returns The empty computation which returns the new state.
*/
export const tell =
<W>(w: W): Writer<W, []> =>
() => [[], w];
<W>(w: W): Writer<W, void> =>
() => [undefined, w];
/**
* Creates an action that executes `writer` and adds its output to the value of the computation.
*
Expand Down
4 changes: 2 additions & 2 deletions src/writer/monad.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,15 @@ import type { Monad } from "../type-class/monad.js";
import type { Monoid } from "../type-class/monoid.js";

export interface MonadWriter<W, M> extends Monoid<W>, Monad<M> {
readonly tell: (output: W) => Get1<M, []>;
readonly tell: (output: W) => Get1<M, void>;
readonly listen: <A>(action: Get1<M, A>) => Get1<M, [A, W]>;
readonly pass: <A>(action: Get1<M, [A, (output: W) => W]>) => Get1<M, A>;
}

export const writer =
<W, M>(mw: MonadWriter<W, M>) =>
<A>([a, w]: readonly [A, W]): Get1<M, A> =>
mw.flatMap<[], A>(() => mw.pure(a))(mw.tell(w));
mw.flatMap<void, A>(() => mw.pure(a))(mw.tell(w));

export const listens =
<W, M>(mw: MonadWriter<W, M>) =>
Expand Down

0 comments on commit f7efc73

Please sign in to comment.