Monad interfaces
npm install @sweet-monads/interfacesCollection of interfaces which describe functional programming abstractions.
> sweet-monads — easy-to-use monads implementation with static types definition and separated packages.
- No dependencies, one small file
- Easily auditable TypeScript/JS code
- Check out all libraries:
either,
iterator,
interfaces,
maybe
identity
> npm install @sweet-monads/interfaces
``typescript
import { Functor } from "@sweet-monads/interfaces";
class MyClass
map(fn: (i: T) => A): MyClass {
return new MyClass();
}
}
`
- Functor
- AsyncFunctor
- Alternative
- Applicative
- AsyncApplicative
- Monad
- AsyncMonad
- AsyncChainable
https://wiki.haskell.org/Functor
An abstract datatype Functor, which has the ability for it's value(s) to be mapped over can become an instance of the Functor interface. That is to say, a new Functor, Functor can be made from Functor by transforming all of it's value(s), whilst leaving the structure of f itself unmodified.
Functors are required to obey certain laws in regards to their mapping. Ensuring instances of Functor obey these laws means the behaviour of fmap remains predictable.
Methods:
##### Functor#map
`typescript`
function map(f: (x: A) => B): Functor;
#### Minimal Complete Definition
`typescript`
map(f: (x: A) => B): Functor;
#### Functor Laws
##### Functors must preserve identity morphisms
`typescript
const f = new SomeFunctorImplementation(); // for all functors
const id = x => x;
expect(f.map(id)).toEqual(f);
`
##### Functors preserve composition of morphisms
`typescript
declare function twice(x: number): number; // for all functions
declare function toString(x: number): string; // for all functions
const f = new SomeFunctorImplementation
expect(f.map(x => toString(twice(x)))).toEqual(f.map(twice).map(toString));
`
Async version of Functor, which provides async version of the map method.
Methods:
##### AsyncFunctor#asyncMap
`typescript`
function asyncMap(f: (x: A) => Promise): Promise
#### Minimal Complete Definition
Functor implementation.
`typescript`
asyncMap(f: (x: A) => Promise): Promise
#### AsyncFunctor Laws
All the 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
declare function toString(x: number): Promise
Promise.resolve(toString(twice(x)))
const f = new SomeAsyncFunctorImplementation
expect(await f.asyncMap(x => twice(x).then(toString))).toEqual(await f.asyncMap(twice).then(f => f.asyncMap(toString)));
`
https://en.wikibooks.org/wiki/Haskell/Alternative_and_MonadPlus
Several classes (Applicative, Monad) have "monoidal" subclasses, intended to model computations that support "failure" and "choice" (in some appropriate sense).
The basic intuition is that empty represents some sort of "failure", and or represents a choice between alternatives. (However, this intuition does not fully capture the nuance possible; see the section on Laws below.) Of course, or should be associative and empty should be the identity element for it. Instances of Alternative must implement empty and or; some and many have default implementations but are included in the class since specialized implementations may be more efficient than the default.
Current implementation is not fully port of Alternative from Haskell, because we don't make the interface an child interface of Applicative and dropped empty static member for ability to implement Alternative for classes like Either.
Methods:
##### Alternative#or
`typescript`
function or
https://wiki.haskell.org/Applicative_functor
This module describes a structure intermediate between a functor and a monad (technically, a strong lax monoidal functor). Compared with monads, this interface lacks the full power of the binding operation chain.
Methods:
##### Applicative.from
`typescript`
function from(x: A): Applicative;
##### Applicative#apply
`typescript`
function apply(this: Applicative<(a: A) => B>, arg: Applicative): Applicative;
function apply(this: Applicative, fn: Applicative<(a: A) => B>): Applicative;
#### Minimal Complete Definition
Functor implementation.
`typescript`
static from(x: A): Applicative;
`typescript`
apply(this: Applicative<(a: A) => B>, arg: Applicative): Applicative;
apply(this: Applicative, fn: Applicative<(a: A) => B>): Applicative;
#### Applicative Laws
##### Identity Law
`typescript
declare var x: Applicative
const id = x => x;
expect(SomeApplicative.from(id).apply(x)).toEqual(x);
`
##### Homomorphism Law
`typescript
declare var x: unknown;
declare var f: (x: unknown) => unknown;
expect(SomeApplicative.from(f).apply(x)).toEqual(SomeApplicative.from(f(x)));
`
Async version of Applicative, which provides async version of the apply method.
Methods:
##### AsyncApplicative#asyncApply
`typescript`
function asyncApply(this: AsyncApplicative<(a: A) => Promise>, arg: AsyncApplicative
function asyncApply(this: AsyncApplicative
#### Minimal Complete Definition
Applicative implementation.
AsyncFunctor implementation.
`typescript`
asyncApply(this: AsyncApplicative<(a: A) => Promise>, arg: AsyncApplicative
asyncApply(this: AsyncApplicative
#### AsyncApplicative Laws
All the Applicative Laws should be applied to the async version, so:
##### Identity Law
`typescript
declare var x: AsyncApplicative
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
expect(await SomeAsyncApplicative.from(f).asyncApply(x)).toEqual(SomeAsyncApplicative.from(await f(x)));
`
https://wiki.haskell.org/Monad
Monads can be thought of as composable computation descriptions. The essence of monad is thus separation of composition timeline from the composed computation's execution timeline, as well as the ability of computation to implicitly carry extra data, as pertaining to the computation itself, in addition to its one (hence the name) output, that it will produce when run (or queried, or called upon). This lends monads to supplementing pure calculations with features like I/O, common environment, updatable state, etc.
Methods:
##### Monad#chain
`typescript`
function chain(f: (x: A) => Monad): Monad;
##### Monad#join
`typescript`
function join
#### Minimal Complete Definition
Applicative implementation.
`typescript`
chain(f: (x: A) => Monad): Monad;
join
#### Monad Laws
##### Left identity Law
`typescript
declare var x: unknown;
declare function f(x: unknown): Monad
expect(SomeMonad.from(x).chain(f)).toEqual(f(x));
`
##### Right identity Law
`typescript
declare var mx: Monad
declare function f(x: unknown): Monad
expect(mx.chain(SomeMonad.from)).toEqual(mx);
`
##### Associativity Law
`typescript
declare var mx: Monad
declare function f(x: unknown): Monad
declare function g(x: unknown): Monad
expect(mx.chain(x => f(x).chain(g))).toEqual(mx.chain(f).chain(g));
`
Async version of Monad, which provides async version of the chain method.
Methods:
##### Monad#chain
`typescript`
function asyncChain(f: (x: A) => Promise
#### Minimal Complete Definition
Monad implementation.
AsyncApplicative implementation.
`typescript`
asyncChain(f: (x: A) => Promise
#### AsyncMonad Laws
All the Monad Laws should be applied to the async version, so:
##### Left identity Law
`typescript
declare var x: unknown;
declare function f(x: unknown): Promise
expect(await SomeAsyncMonad.from(x).asyncChain(f)).toEqual(await f(x));
`
##### Right identity Law
`typescript
declare var mx: AsyncMonad
declare function f(x: unknown): Promise
expect(await mx.asyncChain(x => Promise.resolve(SomeAsyncMonad.from(x)))).toEqual(mx);
`
##### Associativity Law
`typescript
declare var ax: AsyncMonad
declare function f(x: unknown): Promise
declare function g(x: unknown): Promise
expect(await ax.asyncChain(x => f(x).then(fx => fx.asyncChain(g)))).toEqual(await ax.asyncChain(f).then(fx => fx.asyncChain(g)));
`
Static interface which give an ability to use AsyncMonad more comfortable with Promise.
> Should be used with ClassImplements decorator
Methods:
##### AsyncChainable
`typescript`
function chain(f: (v: A) => Promise
#### Usage
`typescript
@ClassImplements
class IdentityMonad
declare function getAsyncValue(): Promise
declare function sendToServer(value: number): Promise
const value = await getAsyncValue().then(chain(sendToServer));
`
Is a value wrapper, that allows to get value (if state of the container is valid), or throws error if not.
Methods:
##### Container#unwrap
`typescript
const lucky = Math.random() > 0.5 ? just(":)") : none();
// Will either return ":)" or throw an error
lucky.unwrap();
``
MIT (c) Artem Kobzar see LICENSE file.