Skip to content

Commit

Permalink
feat(interface): create interfaces which comprise monad
Browse files Browse the repository at this point in the history
All of the interfaces which comprise basic monads with at least one type argument are added.
Functor, Apply, Chain, Applicative, and Monad are added, as well as HKT, which is used for
type-level mapping enabling higher kinded types.
  • Loading branch information
williamareynolds committed Jan 2, 2020
1 parent 903c848 commit 445cd08
Show file tree
Hide file tree
Showing 9 changed files with 90 additions and 4 deletions.
9 changes: 9 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,12 @@

A static-land and fantasy-land compliant library containing interfaces for common type-classes and
common instances of them.

## Documentation

[Theory and Usage][theory-doc]

[API Docs][api-doc]

[api-doc]: https://williamareynolds.github.io/ts-cat/
[theory-doc]: https://github.com/williamareynolds/ts-cat/wiki
6 changes: 6 additions & 0 deletions src/Applicative.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { Type, URIs } from './HKT'
import { ApplyS1 } from './Apply'

export interface ApplicativeS1<F extends URIs> extends ApplyS1<F> {
readonly of: <A>(a: A) => Type<F, A>
}
10 changes: 10 additions & 0 deletions src/Apply.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { Type, URIs } from './HKT'
import { Functor1, FunctorS1 } from './Functor'

export interface Apply1<F extends URIs, A> extends Functor1<F, A> {
readonly ap: <B>(fab: Type<F, (a: A) => B>) => Type<F, B>
}

export interface ApplyS1<F extends URIs> extends FunctorS1<F> {
readonly ap: <A, B>(fab: Type<F, (a: A) => B>, fa: Type<F, A>) => Type<F, B>
}
10 changes: 10 additions & 0 deletions src/Chain.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { Type, URIs } from './HKT'
import { Apply1, ApplyS1 } from './Apply'

export interface Chain1<F extends URIs, A> extends Apply1<F, A> {
chain: <B>(mab: Type<F, (a: A) => Type<F, B>>) => Type<F, B>
}

export interface ChainS1<F extends URIs> extends ApplyS1<F> {
chain: <A, B>(mab: Type<F, (a: A) => Type<F, B>>, ma: Type<F, A>) => Type<F, B>
}
17 changes: 17 additions & 0 deletions src/Functor.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { Type, Type2, URI2s, URIs } from './HKT'

export interface Functor1<F extends URIs, A> {
readonly map: <B>(f: (a: A) => B) => Type<F, B>
}

export interface FunctorS1<F extends URIs> {
readonly map: <A, B>(f: (a: A) => B, fa: Type<F, A>) => Type<F, B>
}

export interface Functor2<F extends URI2s, A, B> {
readonly map: <C>(f: (b: B) => C) => Type2<F, A, C>
}

export interface FunctorS2<F extends URI2s> {
readonly map: <A, B, C>(f: (b: B) => C, fab: Type2<F, A, B>) => Type2<F, A, C>
}
21 changes: 21 additions & 0 deletions src/HKT.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
export interface HKT<URI, A> {
_URI: URI
_A: A
}

export interface URItoHKT<A> {}

export type URIs = keyof URItoHKT<any>

export type Type<URI extends URIs, A> = URItoHKT<A>[URI]

export interface HKT2<URI, A, B> {
_URI: URI
_A: A
}

export interface URItoHKT2<A, B> {}

export type URI2s = keyof URItoHKT2<any, any>

export type Type2<URI extends URI2s, A, B> = URItoHKT2<A, B>[URI]
10 changes: 10 additions & 0 deletions src/Monad.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { Chain1, ChainS1 } from './Chain'
import { Type, URIs } from './HKT'
import { Apply1 } from './Apply'
import { ApplicativeS1 } from './Applicative'

export interface Monad1<M extends URIs, A> extends Apply1<M, A>, Chain1<M, A> {}

export interface MonadS1<M extends URIs> extends ApplicativeS1<M>, ChainS1<M> {
pure: <A>(a: A) => Type<M, A>
}
4 changes: 2 additions & 2 deletions test/ts-cat.test.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import DummyClass from '../src/ts-cat'

/**
* Dummy test
*/
import DummyClass from '../src/ts-cat'

describe('Dummy test', () => {
it('works if true is truthy', () => {
expect(true).toBeTruthy()
Expand Down
7 changes: 5 additions & 2 deletions tslint.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,8 @@
"extends": [
"tslint-config-standard",
"tslint-config-prettier"
]
}
],
"rules": {
"class-name": false
}
}

0 comments on commit 445cd08

Please sign in to comment.