-
Notifications
You must be signed in to change notification settings - Fork 2
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
New Method! #12
Comments
Fair warning: there's still a few edge case bugs in that sample, it's still very early POC. const arrayFunctor: StaticFunctor<ArrayProp> = {
map: <A, B>(fn: (a: A) => B, fa: A): B[] => {
return fa.map(fn);
}
}; For example, this doesn't give an error, but it should, since Reproducible problem: const problem: {
map<F extends any[], U>(
transform: (a: (typeof mappable extends Array<infer T> ? T[] : never)[0]) => U,
mappable: F
): U[];
} = {
map: <A, B>(fn: (a: A) => B, fa: A): B[] => {
return fa.map(fn);
}
}; |
Sorry for the slight spam, but I know people read these issues through email, the issue was with covariance, it's fixed now. Note that this also works in 3.4.3 (needed Sample: // Functor
interface StaticFunctor<P extends TypeProp> {
map<T, U>(transform: (a: T) => U, mappable: Of<P, [T]>): Of<P, [U]>;
}
// Prop
interface ArrayProp extends TypeProp {
params: this["args"][0] extends Array<infer T> ? [T] : never;
type: this["args"][0][];
}
// Examples
const arrayFunctor: StaticFunctor<ArrayProp> = {
map: <A, B>(fn: (a: A) => B, fa: A[]): B[] => {
return fa.map(fn);
}
};
// TypeProps Library
interface TypeProp {
args: any[];
params: unknown[];
type: unknown;
}
type From<Prop extends TypeProp, T = Of<Prop>> = (Prop & { args: [T] })["params"];
type Of<Prop extends TypeProp, T extends unknown[] = unknown[]> = (Prop & {
args: T;
})["type"]; |
link to the issue? |
I'm not sure what issue you refer to, there's several that were mentioned in this issue. I originally assumed this new technique would only work in 3.5, due to a weird edge case, but I found a fix already. The core idea that strax showed me though, is just that you can do this: interface TypeFunction {
arguments: unknown[];
result: unknown;
}
interface ToArray extends TypeFunction {
result: Array<this["arguments"][0]>;
}
type ForEach<T, Mapper extends TypeFunction> = (Mapper & { arguments: [T] })["result"];
// type Test = number[]
type Test = ForEach<number, ToArray>; I think this is a novel idea that I haven't seen yet, that allows arbitrary type-level function execution |
So if I understand correctly this is essentially like type-level function manipulation, although in my understanding this doesn't directly convert to/from functions yet in a generics-preserving manner yet. But if we got HKTs already that's actually already pretty big! I imagine @gcanti is gonna be pretty happy! 😄 |
I've been looking at it and it's in some ways a massive improvement over the previous methods, but it doesn't seem to fix the one big problem in that it will still need every project to agree on using the same specific method of doing HKTs. In that sense, I'm not sure if fp-ts for example will benefit all that much. It allows Gcanti to get rid of having to decorate every HKT with a certain symbol though. I was hoping to find a way to make it so, for example Ramda could seamlessly support any HKT library, but I don't think we're there yet. Exciting progress though :) I'm still experimenting with what this new system can do, but it does seem like we're still not able to fully convert from/to/apply generic functions. |
When defining const arrayFunctor: StaticFunctor<ArrayProp> = {
map: (fn, fa) => {
return fa.map(fn);
} // Inferred as `<T, U>(transform: (a: T) => U, mappable: T[]): U[]`
}; Also, the |
Yeah, I have a bunch of different versions, it wasn't meant to be the definitive example yet. For now, I'm just testing out a bunch of things, like this: type Test1 = λ<Not, [True]>; // False
type Test2 = λ<And, [True, False]>; // False
type Test3 = λ<And, [True, True]>; // True
// Boolean
interface True extends Func {
expression: Var<this, 0>;
}
interface False extends Func {
expression: Var<this, 1>;
}
interface Not extends Func {
expression: λ<Var<this, 0>, [False, True]>
}
interface And extends Func {
expression: λ<Var<this, 0>, [Var<this, 1>, Var<this, 0>]>
}
// Plumbing
type Func = {
variables: Func[];
expression: unknown;
}
type Var<F extends Func, X extends number> = F["variables"][X];
type λ<Exp extends Func, Vars extends unknown[]> = (Exp & {
variables: Vars;
})["expression"]; |
@tycho01 @nadameu @masaeedu
TypeProps will probably be coming back, HKTs just became trivial:
Big thanks to @strax for the new insight. Unfortunately there's a bug in TS 3.4.4 that stops us from using it right now in
typescript@latest
The text was updated successfully, but these errors were encountered: