The library's documentation showcases a very elegant type-level function pipeline:
interface Append<Suffix extends string> extends TypeLambda<[s: string], string> {
return: `${Arg0<this>}${Suffix}`;
}
type ConcatNames = Flow<
Filter<Flow<StringLength, NotExtend<1 | 2>>>,
Take<3>,
Map<CapitalizeString>,
JoinBy<", ">,
Append<", ...">
>;
type Names = ["alice", "bob", "i", "charlie", "david"];
type _ = Call1<ConcatNames, Names>; // => "Alice, Bob, Charlie, ..."
After experimenting with the lib, a common need that I ended up having is the ability to bind type-lambdas to a runtime implementation, and to be able to compose them together.
I have made a primitive attempt using the following approach:
export interface TypeLambdaFn<
L extends TypeLambda1,
> extends TypeLambdaFnBrand<L> {
<const A>(value: A): Call1<L, A>;
}
A common pattern I have encountered is the definition of type-lambda functions that both accept another type-lambda function as input, and return a type-lambda function as output.
Example application with a tag-based dependent-typing library:
// dependent.ts
export const flowUniform = <F extends TypeLambdaFn<any>>(
f: F,
): TypeLambdaFn<FlowUniformLambda<ExtractLambda<F>>> => { ... }
// consumer.ts
const evolve = A.fn((_a: A) =>
Dep.match({ B: (_b: B) => 'A-B' as const, C: (_c: C) => 'A-C' as const }),
);
const mapped = pipe(evolve, Dep.flowUniform(Dep.flowUniform(Result.okL)));
typeof evolve (inferred):
const evolve: Dep.DepFn<{
A: {
in: [A]
out: Dep.DepFn<{
B: {
in: [_b: B]
out: 'A-B'
}
C: {
in: [_c: C]
out: 'A-C'
}
}>
}
}>
typeof mapped (inferred):
const mapped: Dep.DepFn<{
A: {
in: [A]
out: Dep.DepFn<{
B: {
in: [_b: B]
out: Result.Result<'A-B', never>
}
C: {
in: [_c: C]
out: Result.Result<'A-C', never>
}
}>
}
}>
I was wondering if you had experimented with approaches around the interaction of type-level functions and runtime functions. I find the ability to write properly generic runtime functions (that is, generic function that correctly compose with other generic functions) extremely compelling.
The library's documentation showcases a very elegant type-level function pipeline:
After experimenting with the lib, a common need that I ended up having is the ability to bind type-lambdas to a runtime implementation, and to be able to compose them together.
I have made a primitive attempt using the following approach:
A common pattern I have encountered is the definition of type-lambda functions that both accept another type-lambda function as input, and return a type-lambda function as output.
Example application with a tag-based dependent-typing library:
I was wondering if you had experimented with approaches around the interaction of type-level functions and runtime functions. I find the ability to write properly generic runtime functions (that is, generic function that correctly compose with other generic functions) extremely compelling.