You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Because it is not transitive, generics are discarded during inference,
so we need the type constructor to be transitive,
and this requires that the type constructor must be independent
with transitivity and independence, this will be
declarefunctionfoo<T>(v: T): Ttypeparams=Parameters<typeoffoo>// type params = type<T> [v: T]typerets=ReturnType<typeoffoo>// type rets = type<T> T
Independent type constructor should not exist at runtime,
so when an independent type constructor is used as a type without being applied,
the generic type should be discarded again
leta: ReturnType<typeoffoo><1>// let a: 1let b: Parameters<typeoffoo><1>// let b: [v: 1]let c: ReturnType<typeoffoo>// let c: unknownletd: Parameters<typeoffoo>// let d: [v: unknown]
The transitivity of type constructors should also exist on type aliases
typeparams=type<T>[v: T]// type params<T> = [v: T]typerets=type<T>T// type rets<T> = T
*
This type syntax is very loose,
You can represent not only type constructors with parameters,
but also type constructors without parameters,
or you can optionally fill in the return type in the type parameter
typenum=typenumber// type num = number
typeFoo<Textendstype<A,B>A|B>=T// This means T extends type<A, B> => R where R extends A | B// or like associated-types in rust | swift// type<A, B> {// type R: A | B// }typeBar<Textendstype<A>>=T// For external T extends type<A> => unknown// For internal T extends type<A> => anonymous nominal unique type
Variadic Generics
The current improvised solution is
typeFoo<Textendsany[]>=T
Normally this is enough, but it is not free enough when the type constructor is transitive
if has variadic generics, then the type constructor can be inferred
Variadic syntax
typeFoo<...Textendsany[]>=TtypeBar=Foo<1,2,3>// type Bar = [1, 2, 3]
Infer TypeReturnType
typeTypeReturnType<Textendstype<...Aextendsany[]> any>=Textendstype<...Aextendsany[]> infer R ? R : neverinterfaceFoo<T>{a: T}typeBar<A,B>=A|Btypeuse=TypeReturnType<Foo>// return type<T> { a: T } or return Footypeuse=TypeReturnType<Bar>// return type<A, B> A | B
Infer TypeParameters
typeTypeParameters<Textendstype<...Aextendsany[]> any>=Textendstype<...Aextends infer P> any ? P : nevertypeFoo<A,B>=anytypeuse=TypeParameters<Foo>// return type<A, B> [A, B]
Compatibility
It is a pity that although this type syntax is very readable, it has compatibility issues
typetype=1typefoo=type
Other possible syntax
typeA=type: anytypeA=type<B>: anytypeA=type: any
type A=type:<B>anytypeA=(type=any)typeA=(type<B>=any)typeA=~anytypeA=~<B>anytypeA=anytypeA=<B>anytypeA=foranytypeA=for<B>any
What is First class Type constructor
* -> * is type constructor (* -> *) -> * is HKT * -> * -> * is binary type constructor with currying (* -> *) -> (* -> *) is first class type constructor without currying but with transitivity, independent
type<T>.Foo=[T]typefoo=1.Foo// foo is [1]type<A>.Bar<B>=[A,B]typebar=1.Bar<2>// bar is [1, 2]
type<O>.Omit<K>=Omit<O,K>type<O>.Keys=keyofOtype<O>.Vals=O[O.Keys]type<O>.Map<Fextendsfor<[O.Keys,O.Vals]>>={[KinO.Keys]: F<K,O[K]>}typeOmitValue<O,T>=O.Omit<O.Map<for<K,V>VextendsT ? K : never>.Vals>// same totypeOmitValue<O,T>=Omit<O,{[KinkeyofO]: O[K]extendsT ? K : never}[keyofO]>
Search Terms
first class type alias constructor hkt variadic generics transitivity independent independence first-class first-class-type first-class-type-alias first-class-type-constructor variadic-generics higher-kinded-types hrt higher kinded rank types rank-n
Suggestion
Add first class type constructor support
This proposal contains the following features
HKT
The following uses this
'type' ('<' <args>,+ '>')? <return>?
syntaxalthough this syntax has compatibility issues
This is already very useful, but there are many other problems
Transitivity & Independence
Playground
Because it is not transitive, generics are discarded during inference,
so we need the type constructor to be transitive,
and this requires that the type constructor must be independent
with transitivity and independence, this will be
Independent type constructor should not exist at runtime,
so when an independent type constructor is used as a type without being applied,
the generic type should be discarded again
The transitivity of type constructors should also exist on type aliases
*
This
type
syntax is very loose,You can represent not only type constructors with parameters,
but also type constructors without parameters,
or you can optionally fill in the return type in the type parameter
Variadic Generics
The current improvised solution is
Normally this is enough, but it is not free enough when the type constructor is transitive
if has variadic generics, then the type constructor can be inferred
Variadic syntax
Infer TypeReturnType
Infer TypeParameters
Compatibility
It is a pity that although this
type
syntax is very readable, it has compatibility issuesOther possible syntax
What is First class Type constructor
* -> *
is type constructor(* -> *) -> *
is HKT* -> * -> *
is binary type constructor with currying(* -> *) -> (* -> *)
is first class type constructor without currying but with transitivity, independentExamples
Checklist
My suggestion meets these guidelines:
Reference
#1213
#1213 (comment)
#5959
#29904
#30215
#31116
#41040
#44875
#48036
#48820
first-class-protocols
The text was updated successfully, but these errors were encountered: