@sweet-monads/interfaces
Advanced tools
Comparing version 2.3.0 to 3.0.0
@@ -6,4 +6,2 @@ import type { Functor } from "./functor"; | ||
apply<A, B>(this: Applicative<A>, fn: Applicative<(a: A) => B>): Applicative<B>; | ||
asyncApply<A, B>(this: Applicative<(a: A) => Promise<B>>, arg: Applicative<Promise<A> | A>): Promise<Applicative<B>>; | ||
asyncApply<A, B>(this: Applicative<Promise<A> | A>, fn: Applicative<(a: A) => Promise<B>>): Promise<Applicative<B>>; | ||
} | ||
@@ -10,0 +8,0 @@ |
@@ -1,5 +0,5 @@ | ||
import type { Monad } from "@sweet-monads/interfaces"; | ||
import type { AsyncMonad } from "./async-monad"; | ||
export interface AsyncChainable<M extends Monad<unknown>> { | ||
chain<A, B>(f: (v: A) => Promise<M & Monad<B>>): (m: M & Monad<A>) => Promise<M & Monad<B>>; | ||
export interface AsyncChainable<M extends AsyncMonad<unknown>> { | ||
chain<A, B>(f: (v: A) => Promise<M & AsyncMonad<B>>): (m: M & AsyncMonad<A>) => Promise<M & AsyncMonad<B>>; | ||
} |
@@ -1,1 +0,7 @@ | ||
export declare function ClassImplements<T>(): (constructor: T) => void; | ||
type UnionToIntersection<U> = (U extends any ? (k: U) => void : never) extends (k: infer I) => void ? I : never; | ||
type TupleToUnion<T extends any[]> = T[number]; | ||
type TupleToIntersection<T extends any[]> = UnionToIntersection<TupleToUnion<T>>; | ||
export type ClassImplements<C extends TupleToIntersection<I>, I extends any[]> = C; |
export interface Functor<T> { | ||
map<R>(f: (a: T) => R): Functor<R>; | ||
asyncMap<R>(f: (a: T) => Promise<R>): Promise<Functor<R>>; | ||
} |
export type { Functor } from "./functor"; | ||
export type { AsyncMonad } from "./async-monad"; | ||
export type { Alternative } from "./alternative"; | ||
export type { AsyncFunctor } from "./async-functor"; | ||
export type { AsyncChainable } from "./async-chainable"; | ||
export type { ClassImplements } from "./class-implements"; | ||
export type { AsyncApplicative } from "./async-applicative"; | ||
export type { Monad, MonadConstructor } from "./monad"; | ||
export type { Applicative, ApplicativeConstructor } from "./applicative"; | ||
export { ClassImplements } from "./class-implements"; |
@@ -5,3 +5,2 @@ import type { Applicative, ApplicativeConstructor } from "./applicative"; | ||
chain<B>(f: (a: T) => Monad<B>): Monad<B>; | ||
asyncChain<B>(f: (a: T) => Promise<Monad<B>>): Promise<Monad<B>>; | ||
join<I>(this: Monad<Monad<I>>): Monad<I>; | ||
@@ -8,0 +7,0 @@ } |
{ | ||
"name": "@sweet-monads/interfaces", | ||
"version": "2.3.0", | ||
"version": "3.0.0", | ||
"description": "Monad interfaces", | ||
@@ -5,0 +5,0 @@ "main": "index.js", |
161
README.md
@@ -12,6 +12,6 @@ # @sweet-monads/interfaces | ||
- Check out all libraries: | ||
[either](https://github.com/JSMonk/sweet-monads/tree/master/either), | ||
[either](https://github.com/JSMonk/sweet-monads/tree/master/either), | ||
[iterator](https://github.com/JSMonk/sweet-monads/tree/master/iterator), | ||
[interfaces](https://github.com/JSMonk/sweet-monads/tree/master/interfaces), | ||
[maybe](https://github.com/JSMonk/sweet-monads/tree/master/maybe), | ||
[maybe](https://github.com/JSMonk/sweet-monads/tree/master/maybe) | ||
@@ -35,5 +35,8 @@ ## Usage | ||
- [`Functor`](#functor) | ||
- [`AsyncFunctor`](#asyncfunctor) | ||
- [`Alternative`](#alternative) | ||
- [`Applicative`](#applicative) | ||
- [`AsyncApplicative`](#asyncapplicative) | ||
- [`Monad`](#monad) | ||
- [`AsyncMonad`](#asyncmonad) | ||
- [`AsyncChainable`](#asyncchainable) | ||
@@ -85,2 +88,45 @@ | ||
### AsyncFunctor | ||
Async version of [`Functor`](#functor), which provides async version of the [`map`](#functormap) method. | ||
Methods: | ||
##### `AsyncFunctor#asyncMap` | ||
```typescript | ||
function asyncMap<A, B>(f: (x: A) => Promise<B>): Promise<AsyncFunctor<B>>; | ||
``` | ||
#### Minimal Complete Definition | ||
[`Functor`](#functor) implementation. | ||
```typescript | ||
asyncMap<A, B>(f: (x: A) => Promise<B>): Promise<AsyncFunctor<B>>; | ||
``` | ||
#### AsyncFunctor Laws | ||
All the [`Functor Laws`](#functor-laws) should be applied to the async version, so: | ||
##### AsyncFunctors must preserve identity morphisms | ||
```typescript | ||
const f = new SomeAsyncFunctorImplementation(); // for all functors | ||
const id = x => Promise.resolve(x); | ||
expect(await f.asyncMap(id)).toEqual(f); | ||
``` | ||
##### AsyncFunctors preserve composition of morphisms | ||
```typescript | ||
declare function twice(x: number): Promise<number>; // for all functions | ||
declare function toString(x: number): Promise<string>; // for all functions | ||
Promise.resolve(toString(twice(x))) | ||
const f = new SomeAsyncFunctorImplementation<number>(); | ||
expect(await f.asyncMap(x => twice(x).then(toString))).toEqual(await f.asyncMap(twice).then(f => f.asyncMap(toString))); | ||
``` | ||
### Alternative | ||
@@ -120,4 +166,4 @@ | ||
```typescript | ||
apply<A, B>(this: Applicative<(a: A) => B>, arg: Applicative<A>): Applicative<B>; | ||
apply<A, B>(this: Applicative<A>, fn: Applicative<(a: A) => B>): Applicative<B>; | ||
function apply<A, B>(this: Applicative<(a: A) => B>, arg: Applicative<A>): Applicative<B>; | ||
function apply<A, B>(this: Applicative<A>, fn: Applicative<(a: A) => B>): Applicative<B>; | ||
``` | ||
@@ -158,2 +204,48 @@ | ||
### AsyncApplicative | ||
Async version of [`Applicative`](#applicative), which provides async version of the [`apply`](#applicativeapply) method. | ||
Methods: | ||
##### `AsyncApplicative#asyncApply` | ||
```typescript | ||
function asyncApply<A, B>(this: AsyncApplicative<(a: A) => Promise<B>>, arg: AsyncApplicative<Promise<A> | A>): Promise<AsyncApplicative<B>>; | ||
function asyncApply<A, B>(this: AsyncApplicative<Promise<A> | A>, fn: AsyncApplicative<(a: A) => Promise<B>>): Promise<AsyncApplicative<B>>; | ||
``` | ||
#### Minimal Complete Definition | ||
[`Applicative`](#applicative) implementation. | ||
[`AsyncFunctor`](#asyncfunctor) implementation. | ||
```typescript | ||
asyncApply<A, B>(this: AsyncApplicative<(a: A) => Promise<B>>, arg: AsyncApplicative<Promise<A> | A>): Promise<AsyncApplicative<B>>; | ||
asyncApply<A, B>(this: AsyncApplicative<Promise<A> | A>, fn: AsyncApplicative<(a: A) => Promise<B>>): Promise<AsyncApplicative<B>>; | ||
``` | ||
#### AsyncApplicative Laws | ||
All the [`Applicative Laws`](#applicative-laws) should be applied to the async version, so: | ||
##### Identity Law | ||
```typescript | ||
declare var x: AsyncApplicative<unknown>; | ||
const id = x => Promise.resolve(x); | ||
expect(await SomeAsyncApplicative.from(id).asyncApply(x)).toEqual(x); | ||
``` | ||
##### Homomorphism Law | ||
```typescript | ||
declare var x: unknown; | ||
declare var f: (x: unknown) => Promise<unknown>; | ||
expect(await SomeAsyncApplicative.from(f).asyncApply(x)).toEqual(SomeAsyncApplicative.from(await f(x))); | ||
``` | ||
### Monad | ||
@@ -218,5 +310,60 @@ | ||
### AsyncMonad | ||
Async version of [`Monad`](#monad), which provides async version of the [`chain`](#applicativeapply) method. | ||
Methods: | ||
##### `Monad#chain` | ||
```typescript | ||
function asyncChain<A, B>(f: (x: A) => Promise<AsyncMonad<B>>): Promise<AsyncMonad<B>>; | ||
``` | ||
#### Minimal Complete Definition | ||
[`Monad`](#monad) implementation. | ||
[`AsyncApplicative`](#applicative) implementation. | ||
```typescript | ||
asyncChain<A, B>(f: (x: A) => Promise<AsyncMonad<B>>): Promise<Monad<B>>; | ||
``` | ||
#### AsyncMonad Laws | ||
All the [`Monad Laws`](#monad-laws) should be applied to the async version, so: | ||
##### Left identity Law | ||
```typescript | ||
declare var x: unknown; | ||
declare function f(x: unknown): Promise<AsyncMonad<unknown>>; | ||
expect(await SomeAsyncMonad.from(x).asyncChain(f)).toEqual(await f(x)); | ||
``` | ||
##### Right identity Law | ||
```typescript | ||
declare var mx: AsyncMonad<unknown>; | ||
declare function f(x: unknown): Promise<AsyncMonad<unknown>>; | ||
expect(await mx.asyncChain(x => Promise.resolve(SomeAsyncMonad.from(x)))).toEqual(mx); | ||
``` | ||
##### Associativity Law | ||
```typescript | ||
declare var ax: AsyncMonad<unknown>; | ||
declare function f(x: unknown): Promise<AsyncMonad<unknown>>; | ||
declare function g(x: unknown): Promise<AsyncMonad<unknown>>; | ||
expect(await ax.asyncChain(x => f(x).then(fx => fx.asyncChain(g)))).toEqual(await ax.asyncChain(f).then(fx => fx.asyncChain(g))); | ||
``` | ||
### AsyncChainable | ||
Static interface which give an ability to use `Monad` more comfortable with `Promise`. | ||
Static interface which give an ability to use `AsyncMonad` more comfortable with `Promise`. | ||
@@ -230,3 +377,3 @@ > Should be used with `ClassImplements` decorator | ||
```typescript | ||
function chain<A, B>(f: (v: A) => Promise<M & Monad<B>>): (m: M & Monad<A>) => Promise<M & Monad<B>>; | ||
function chain<A, B>(f: (v: A) => Promise<M & AsyncMonad<B>>): (m: M & AsyncMonad<A>) => Promise<M & AsyncMonad<B>>; | ||
``` | ||
@@ -238,3 +385,3 @@ | ||
@ClassImplements<IdentityMonad<unknown>> | ||
class IdentityMonad<T> extends Monad<T> { /*...*/ } | ||
class IdentityMonad<T> extends AsyncMonad<T> { /*...*/ } | ||
@@ -241,0 +388,0 @@ declare function getAsyncValue(): Promise<IdentityMonad<number>> |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
15083
13
52
389