Skip to content
This repository has been archived by the owner on May 3, 2021. It is now read-only.

Commit

Permalink
feat: clean up tests
Browse files Browse the repository at this point in the history
* move tests to tests ddirectory
* simplify some option modules
* implement general monad law tests for option and either
* implement more tests for option and either
* add nice names for tests
  • Loading branch information
baetheus committed Sep 11, 2020
1 parent ae1797a commit e4499a0
Show file tree
Hide file tree
Showing 14 changed files with 455 additions and 257 deletions.
19 changes: 19 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# hkts

Higher kinded types for [Deno](https://deno.land). As an avid user of [fp-ts](https://github.com/gcanti/fp-ts) I wanted to have a similarly full featured envvironment in Deno. Unfortunately, the fp-ts port to Deno is clunky to use with other functional libraries like [@nll/datum](https://github.com/nullpub/datum), [io-ts](https://github.com/gcanti/io-ts), and [monocle-ts](https://github.com/gcanti/monocle-ts). While I could have ported fp-ts directly, I've come to like the exploratory work done by pelotom in the original [hkts](http://github.com/pelotom/hkts). Thus, I've decided to port the functionality of fp-ts, io-ts, and monocle-ts to Deno using the HKT substitution developed by pelotom.

## Installation

This library is meant to be used with Deno, thus it follows the [Deno imports](https://deno.land/manual/examples/import_export) syntax.

```ts
import * as O from "https://deno.land/x/hkts/option.ts";
import { pipe } from "https://deno.land/x/hkts/pipe.ts";

const result = pipe(
O.some(1),
O.map(n => n + 1),
O.chain(n => n % 2 === 0 ? O.none, O.some(n))
);
// result = O.none.
```
24 changes: 0 additions & 24 deletions fns.test.ts

This file was deleted.

114 changes: 113 additions & 1 deletion fns.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,12 @@

export type Fn<AS extends unknown[], B> = (...as: AS) => B;

export type Nil = undefined | null;

export type NotNil<A> = Exclude<A, Nil>;

/***************************************************************************************************
* @section Functions
* @section Helper Functions
**************************************************************************************************/

export const curry2 = <A, B, C>(fn: (a: A, b: B) => C) => (a: A) => (b: B): C =>
Expand All @@ -25,3 +29,111 @@ export const compose = <A, B>(fab: (a: A) => B) => <C>(fbc: (b: B) => C) => (
): C => fbc(fab(a));

export const constant = <A>(a: A) => () => a;

// export const isNil = <A>(a: A): a is Nul

/***************************************************************************************************
* @section Pipe
* Original pipe function pulled from fp-ts and modified
* https://github.com/gcanti/fp-ts/blob/master/src/pipeable.ts
**************************************************************************************************/

export function pipe<A>(a: A): A;
export function pipe<A, B>(a: A, ab: (a: A) => B): B;
export function pipe<A, B, C>(a: A, ab: (a: A) => B, bc: (b: B) => C): C;
export function pipe<A, B, C, D>(
a: A,
ab: (a: A) => B,
bc: (b: B) => C,
cd: (c: C) => D
): D;
export function pipe<A, B, C, D, E>(
a: A,
ab: (a: A) => B,
bc: (b: B) => C,
cd: (c: C) => D,
de: (d: D) => E
): E;
export function pipe<A, B, C, D, E, F>(
a: A,
ab: (a: A) => B,
bc: (b: B) => C,
cd: (c: C) => D,
de: (d: D) => E,
ef: (e: E) => F
): F;
export function pipe<A, B, C, D, E, F, G>(
a: A,
ab: (a: A) => B,
bc: (b: B) => C,
cd: (c: C) => D,
de: (d: D) => E,
ef: (e: E) => F,
fg: (f: F) => G
): G;
export function pipe<A, B, C, D, E, F, G, H>(
a: A,
ab: (a: A) => B,
bc: (b: B) => C,
cd: (c: C) => D,
de: (d: D) => E,
ef: (e: E) => F,
fg: (f: F) => G,
gh: (g: G) => H
): H;
export function pipe<A, B, C, D, E, F, G, H, I>(
a: A,
ab: (a: A) => B,
bc: (b: B) => C,
cd: (c: C) => D,
de: (d: D) => E,
ef: (e: E) => F,
fg: (f: F) => G,
gh: (g: G) => H,
hi: (h: H) => I
): I;
export function pipe<A, B, C, D, E, F, G, H, I, J, K>(
a: A,
ab: (a: A) => B,
bc: (b: B) => C,
cd: (c: C) => D,
de: (d: D) => E,
ef: (e: E) => F,
fg: (f: F) => G,
gh: (g: G) => H,
hi: (h: H) => I,
ij: (i: I) => J,
jk: (j: J) => K
): K;
export function pipe<A, B, C, D, E, F, G, H, I, J, K, L>(
a: A,
ab: (a: A) => B,
bc: (b: B) => C,
cd: (c: C) => D,
de: (d: D) => E,
ef: (e: E) => F,
fg: (f: F) => G,
gh: (g: G) => H,
hi: (h: H) => I,
ij: (i: I) => J,
jk: (j: J) => K,
kl: (K: K) => L
): L;
export function pipe<A, B, C, D, E, F, G, H, I, J, K, L>(
a: A,
ab: (a: A) => B,
bc: (b: B) => C,
cd: (c: C) => D,
de: (d: D) => E,
ef: (e: E) => F,
fg: (f: F) => G,
gh: (g: G) => H,
hi: (h: H) => I,
ij: (i: I) => J,
jk: (j: J) => K,
kl: (K: K) => L,
end: never
): L;
export function pipe(a: unknown, ...fns: Function[]): unknown {
return fns.reduce((val, fn) => fn(val), a);
}
2 changes: 1 addition & 1 deletion hkts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ export interface Fixed<T> {
* type ArrayInstance = FunctorFn<Array<_>>;
* // ArrayInstance = <A, B>(fab: (a: A) => B, ta: A[]): B[]
* type RecordInstance = FunctorFn<{ value: _ }>;
* // PromiseInstance = <A, B>(fab: (a: A) => B, ta: { value: A }): { value: B }
* // RecordInstance = <A, B>(fab: (a: A) => B, ta: { value: A }): { value: B }
**************************************************************************************************/

// prettier-ignore
Expand Down
10 changes: 0 additions & 10 deletions option.test.ts

This file was deleted.

10 changes: 6 additions & 4 deletions option.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { compose, identity } from "./fns.ts";
import { $, _ } from "./hkts.ts";
import * as SL from "./type-classes.ts";
import { pipe } from "./pipe.ts";
import { pipe } from "./fns.ts";

/***************************************************************************************************
* @section Types
Expand All @@ -23,6 +23,8 @@ export const getShow = <A>({ show }: SL.Show<A>): SL.Show<Option<A>> => ({
show: (ma) => (isNone(ma) ? "None" : `${"Some"}(${show(ma.value)})`),
});

// export

/***************************************************************************************************
* @section Destructors
**************************************************************************************************/
Expand All @@ -43,8 +45,8 @@ export const isSome = <A>(m: Option<A>): m is Some<A> => m.tag === "Some";

export const Monad = SL.createMonad<Option<_>>({
of: some,
map: (fab, ta) => pipe(ta, fold(compose(fab)(some), constNone)),
join: (tta) => (isNone(tta) ? tta : tta.value),
map: (fab, ta) => (isSome(ta) ? some(fab(ta.value)) : ta),
join: (tta) => (isSome(tta) ? tta.value : tta),
});

export const Applicative: SL.Applicative<Option<_>> = {
Expand All @@ -59,7 +61,7 @@ export const Apply: SL.Apply<Option<_>> = {
};

export const Alternative: SL.Alternative<Option<_>> = {
of: Monad.of,
of: some,
ap: Monad.ap,
map: Monad.map,
zero: constNone,
Expand Down
103 changes: 0 additions & 103 deletions pipe.test.ts

This file was deleted.

0 comments on commit e4499a0

Please sign in to comment.