import type { Erase, UnionToIntersection } from './util/types' /* * ------------------------------------------- * Base * https://github.com/Matechs-Garage/matechs-effect/blob/master/packages/core/src/Prelude/HKT/base.ts * ------------------------------------------- */ export interface Auto { // readonly Auto: unique symbol } export interface Base { readonly _F: F readonly _C: C } export interface BaseHKT { readonly _HKT: unique symbol readonly _URI: F readonly _C: C } export type MapURIS = F extends [URI, ...infer Rest] ? [URI, ...MapURIS] : [] export type CompositionBase2 = Base< [...MapURIS, ...MapURIS] > /* * ------------------------------------------- * Generic Helpers * https://github.com/Matechs-Garage/matechs-effect/blob/master/packages/core/src/Prelude/HKT/hkt.ts * ------------------------------------------- */ export const HKT_URI = 'HKT' export type HKT_URI = typeof HKT_URI export interface HKT { readonly _URI: URI readonly _A: A } export const HKT2_URI = 'HKT2' export type HKT2_URI = typeof HKT2_URI export interface HKT2 extends HKT { readonly _E: E } export const HKT3_URI = 'HKT3' export type HKT3_URI = typeof HKT3_URI export interface HKT3 extends HKT2 { readonly _R: R } export const HKT4_URI = 'HKT4' export type HKT4_URI = typeof HKT4_URI export interface HKT4 extends HKT3 { readonly _S: S } export type UHKT = [URI<'HKT', CustomType<'F', F>>] export type UHKT2 = [URI<'HKT2', CustomType<'F', F>>] export type UHKT3 = [URI<'HKT3', CustomType<'F', F>>] export type UHKT4 = [URI<'HKT4', CustomType<'F', F>>] /* * ------------------------------------------- * HKT Encoding * https://github.com/Matechs-Garage/matechs-effect/blob/master/packages/core/src/Prelude/HKT/hkt.ts * ------------------------------------------- */ /** * A type-level dictionary for HKTs: URI -> Concrete Type */ export interface URItoKind< // encodes metadata carried at the URI level (like additional params) FC, // encodes constraints on parameters and variance at the typeclass level TC, // encodes nominal keys N extends string, // encodes generic keys K, // encodes free logic Q, // encodes free logic W, // encodes free logic X, // encodes free logic I, // encodes free logic S, // encodes free logic R, // encodes free logic E, // encodes output A > { [HKT_URI]: HKT, A> [HKT2_URI]: HKT2, E, A> [HKT3_URI]: HKT3, R, E, A> [HKT4_URI]: HKT4, S, R, E, A> } /** * A type-level dictionary for indexed HKTs */ export interface URItoIndex { [HKT_URI]: K [HKT2_URI]: K [HKT3_URI]: K [HKT4_URI]: K } /* * ------------------------------------------- * Kind Encoding * https://github.com/Matechs-Garage/matechs-effect/blob/master/packages/core/src/Prelude/HKT/kind.ts * ------------------------------------------- */ export type ConcreteURIS = keyof URItoKind export type URIS = [URI, ...URI[]] export interface URI { readonly _F: F readonly _C: C } export type AppendURI> = F extends URIS ? [...F, G] : F export type PrependURI, F extends URIS> = F extends URIS ? [G, ...F] : F export type Rest = F extends [any, ...infer Rest] ? Rest : [] export type Kind = F extends [any, ...infer Next] ? Next extends URIS ? URItoKind< F[0]['_C'], C, OrFix<'N', F[0]['_C'], OrFix<'N', C, N>>, OrFix<'K', F[0]['_C'], OrFix<'K', C, K>>, OrFix<'Q', F[0]['_C'], OrFix<'Q', C, Q>>, OrFix<'W', F[0]['_C'], OrFix<'W', C, W>>, OrFix<'X', F[0]['_C'], OrFix<'X', C, X>>, OrFix<'I', F[0]['_C'], OrFix<'I', C, I>>, OrFix<'S', F[0]['_C'], OrFix<'S', C, S>>, OrFix<'R', F[0]['_C'], OrFix<'R', C, R>>, OrFix<'E', F[0]['_C'], OrFix<'E', C, E>>, Kind >[F[0]['_F']] : URItoKind< F[0]['_C'], C, OrFix<'N', F[0]['_C'], OrFix<'N', C, N>>, OrFix<'K', F[0]['_C'], OrFix<'K', C, K>>, OrFix<'Q', F[0]['_C'], OrFix<'Q', C, Q>>, OrFix<'W', F[0]['_C'], OrFix<'W', C, W>>, OrFix<'X', F[0]['_C'], OrFix<'X', C, X>>, OrFix<'I', F[0]['_C'], OrFix<'I', C, I>>, OrFix<'S', F[0]['_C'], OrFix<'S', C, S>>, OrFix<'R', F[0]['_C'], OrFix<'R', C, R>>, OrFix<'E', F[0]['_C'], OrFix<'E', C, E>>, A >[F[0]['_F']] : never /* * ------------------------------------------- * Inference * https://github.com/Matechs-Garage/matechs-effect/blob/master/packages/core/src/Prelude/HKT/infer.ts * ------------------------------------------- */ export type Infer = [K] extends [ Kind ] ? P extends 'C' ? C : P extends 'N' ? N : P extends 'K' ? K : P extends 'Q' ? Q : P extends 'W' ? W : P extends 'X' ? X : P extends 'I' ? I : P extends 'S' ? S : P extends 'R' ? R : P extends 'E' ? E : P extends 'A' ? A : never : never export type URIOf> = K extends Kind< infer F, any, any, any, any, any, any, any, any, any, any, any > ? F : never export type IndexForBase = F extends keyof URItoIndex ? URItoIndex[F] : K export type IndexFor = IndexForBase< { [K in keyof F]: F[K] extends ConcreteURIS ? F[K] : F[K] extends URI ? U : never }[number], N, K > export type CompositionIndexForBase = 1 extends F['length'] ? F[0] extends keyof URItoIndex ? URItoIndex[F[0]] : K : { [P in keyof F]: F[P] extends keyof URItoIndex ? URItoIndex[F[P]] : K } export type CompositionIndexFor = CompositionIndexForBase< { [K in keyof F]: F[K] extends ConcreteURIS ? F[K] : F[K] extends URI ? U : never }, N, K > /* * ------------------------------------------- * Custom * https://github.com/Matechs-Garage/matechs-effect/blob/master/packages/core/src/Prelude/HKT/custom.ts * ------------------------------------------- */ export interface CustomType

{ CustomType: { [p in P]: () => V } } export type AccessCustom = C extends CustomType ? V : D export type AccessCustomExtends = C extends CustomType ? V extends D ? V : D : D /* * ------------------------------------------- * Fix * https://github.com/Matechs-Garage/matechs-effect/blob/master/packages/core/src/Prelude/HKT/fix.ts * ------------------------------------------- */ export type Param = 'N' | 'K' | 'Q' | 'W' | 'I' | 'X' | 'S' | 'R' | 'E' export interface Fix

{ Fix: { [p in P]: { F: () => F } } } export type OrFix

= A extends Fix ? P extends 'N' ? X extends string ? X : B : X : B export type Unfix = (Exclude extends never ? unknown : { [K in Exclude]: C[K] }) & (keyof C & 'Fix' extends never ? unknown : { [K in keyof C & 'Fix']: { [KK in Exclude]: C[K][KK] } }) export type CleanParam = C extends (Auto | V | V | Fix) & infer X ? X : C /* * ------------------------------------------- * OrNever * https://github.com/Matechs-Garage/matechs-effect/blob/master/packages/core/src/Prelude/HKT/or-never.ts * ------------------------------------------- */ export type OrNever = unknown extends K ? never : K /* * ------------------------------------------- * Variance Encoding * https://github.com/Matechs-Garage/matechs-effect/blob/master/packages/core/src/Prelude/HKT/variance.ts * ------------------------------------------- */ export type Variance = '+' | '-' | '_' export interface V { Variance: { [v in V]: () => F } } /** * Composes types according to variance specified in C */ export type Mix = C extends V ? X[0] : C extends V ? X[number] : C extends V ? X extends [any] ? X[0] : X extends [any, any] ? X[0] & X[1] : X extends [any, any, any] ? X[0] & X[1] & X[2] : X extends [any, any, any, any] ? X[0] & X[1] & X[2] & X[3] : X extends [any, any, any, any, any] ? X[0] & X[1] & X[2] & X[3] & X[4] : X extends [any, any, any, any, any, any] ? X[0] & X[1] & X[2] & X[3] & X[4] & X[5] : UnionToIntersection<{ [k in keyof X]: OrNever }[keyof X]> : X[0] /** * Composes a record of types to the base respecting variance from C */ export type MixStruct = C extends V ? X : C extends V ? Y[keyof Y] : C extends V ? P extends 'N' ? string : UnionToIntersection<{ [k in keyof Y]: OrNever }[keyof Y]> : X /** * Used in subsequent definitions to either vary a paramter or keep it fixed to "Fixed" */ export type Intro = C extends V ? Fixed : C extends V ? Current : C extends V ? Current : Fixed /** * Initial type depending on variance of P in C (eg: initial Contravariant R = unknown, initial Covariant E = never) */ export type Initial = C extends V ? P extends 'N' ? string : unknown : C extends V ? never : any export type Strip = Erase & V & V> /* * ------------------------------------------- * Instance Helpers * https://github.com/Matechs-Garage/matechs-effect/blob/master/packages/core/src/Prelude/HKT/instance.ts * ------------------------------------------- */ export type Ignores = '_F' | '_G' | 'Commutative' | '_C' | '_CF' | '_CG' /** * A helper for constructing typeclass instances */ export const instance = (_: Omit): T => _ as any