Skip to content

Instantly share code, notes, and snippets.

@fvilante
Last active January 21, 2020 18:30
Show Gist options
  • Save fvilante/14dd2350eccfdf1af5a9c7d9ab3763d4 to your computer and use it in GitHub Desktop.
Save fvilante/14dd2350eccfdf1af5a9c7d9ab3763d4 to your computer and use it in GitHub Desktop.
Category Theory Study - 1) Static-Land Higher Kinded implementation attempt 2) A 'how-many-type-parameters' identifier propose
// An idea for arbitrary type-parameters. (see bellow 'InferTArgs')
// === Type Class ===
type TypeClass0<K extends string> = {
readonly kind: 'TypeClass'
readonly __TypeClassName: K
readonly __0: undefined
}
const TypeClass0 = <K extends string>(__TypeClass: K):TypeClass0<K> => ({kind:'TypeClass', __TypeClassName: __TypeClass, __0: undefined})
interface TypeClass1<K extends string, A> extends TypeClass0<K> {
readonly __1: A
}
const TypeClass1 = <K extends string, A>(__TypeClass: K, __1:A):TypeClass1<K,A> => ({kind:'TypeClass', __TypeClassName: __TypeClass, __0: undefined, __1})
interface TypeClass2<K extends string, A, B> extends TypeClass1<K,A>{
readonly __2: B
}
const TypeClass2 = <K extends string, A, B>(__TypeClass: K, __1:A, __2:B):TypeClass2<K,A,B> => ({kind:'TypeClass', __TypeClassName: __TypeClass, __0: undefined, __1, __2})
interface TypeClass3<T extends string, A, B, C> extends TypeClass2<T,A,B> {
readonly __3: C
}
const TypeClass3 = <K extends string, A, B, C>(__TypeClass: K, __1:A, __2:B, __3:C):TypeClass3<K,A,B,C> => ({kind:'TypeClass', __TypeClassName: __TypeClass, __0: undefined, __1, __2, __3})
type _Just<A> = {
readonly kind: 'Just'
readonly value: A
readonly map: <B>(f: (_:A) => B) => _Just<B>
}
type _Nothing<A> = {
readonly kind: 'Nothing'
readonly value: A
}
type TypeConstructor<A> = {
readonly kind: 'TypeConstructor'
readonly __Constructor: (_:A) => _Just<A>
}
type Oco1<A> = {
readonly kind: 'Oco1'
readonly __1: TypeConstructor<A>
}
type Oco2<A,B> = {
readonly kind: 'Oco2'
readonly __1: TypeConstructor<A>
readonly __2: TypeConstructor<B>
}
type Oco3<A,B,C> = {
readonly kind: 'Oco3'
readonly __1: TypeConstructor<A>
readonly __2: TypeConstructor<B>
readonly __3: TypeConstructor<C>
}
type Oco4<A,B,C,D> = {
readonly kind: 'Oco4'
readonly __1: TypeConstructor<A>
readonly __2: TypeConstructor<B>
readonly __3: TypeConstructor<C>
readonly __4: TypeConstructor<D>
}
type InferTArgs<A = undefined, B = undefined, C = undefined, D = undefined> =
D extends undefined ? C extends undefined ? B extends undefined ? A extends undefined ? never :
// '__1' : '__2' : '__3'...etc
Oco1<A> : Oco2<A,B> : Oco3<A,B,C> : Oco4<A,B,C,D>
type Maybe<A> = InferTArgs<number,A>
type B = Maybe<undefined>
// ==== Type Class Instances ===
type Just = InferTArgs<string, number>
// =========== TYPE CONSTRUCTOR ==========
// TYPE CONSTRUCTED
// Objects of type A in a category K
type T<K extends Cats, A> = {
readonly kind: 'ObjectInACategoryK'
readonly extractValue: () => A
readonly extractCat: () => K
}
const T = <K extends Cats, A>(cat:K, value:A):T<K,A> => {
type H = T<K,A>
const extractValue: H['extractValue'] = () => value
const extractCat: H['extractCat'] = () => cat
return {
kind: 'ObjectInACategoryK',
extractValue,
extractCat,
}
}
// =========== ALGEBRIC TYPES ==========
type Cats = string
// Lifts a function from TS0 category to category TK of static paramtrized types (1 type param)
export type Functor<A> = {
readonly map: <B>(f: (_: A) => B) => (a: T<'Fuctor', A>) => T<'Functor', B>
}
// lift an type from TS0-category to TK-catgory
export type Applicative<K extends Cats, A> = {
readonly of: (a:A) => T<K,A>
}
// contramap
export type Contravariant<K extends Cats, A> = {
readonly contramap: <B>(f: (_:A) => B) => T<K,A>
}
// Informal test
const Test00 = () => {
type Just<A> = {readonly kind: 'Just'} & Functor<A>
const Just = <A>(value:A): Just<A> => {
type H = Just<A>
const map: H['map'] = f => Just(f(value))
return {
kind: 'Just',
map,
}
}
const a = Just(10)
const b = a.map()
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment