Skip to content

Instantly share code, notes, and snippets.

@baetheus
Last active January 4, 2023 18:35
Show Gist options
  • Save baetheus/11e3c6d9a0497dd53b3a17fe7459a8be to your computer and use it in GitHub Desktop.
Save baetheus/11e3c6d9a0497dd53b3a17fe7459a8be to your computer and use it in GitHub Desktop.
Testing Deno Doc Gen
import type { $, Kind } from "https://deno.land/x/fun/kind.ts";
import type { Applicative } from "https://deno.land/x/fun/applicative.ts";
import { pipe } from "https://deno.land/x/fun/fn.ts";
export function curry2<A, B, C>(f: (a: A, b: B) => C): (a: A) => (b: B) => C {
return (a) => (b) => f(a, b);
}
export function curry3<A, B, C, D>(
f: (a: A, b: B, c: C) => D,
): (a: A) => (b: B) => (c: C) => D {
return (a) => (b) => (c) => f(a, b, c);
}
export interface Curried2<A, B, C> {
(): Curried2<A, B, C>;
(a: A, b: B): C;
(a: A): (b: B) => C;
}
export function ccurry2<A, B, C>(f: (a: A, b: B) => C): Curried2<A, B, C> {
function curried(a: A, b: B): any {
switch (arguments.length) {
case 0:
return curried;
case 1:
return (b: B) => f(a, b);
default:
return f(a, b);
}
}
return curried as any;
}
export function chain<A, I>(
faui: (a: A) => Promise<I>,
value: Promise<A>,
): Promise<I> {
return value.then(faui);
}
export const chainCurry1 = curry2(chain);
export const chainCurry2: <A, I>(
faui: (a: A) => Promise<I>,
) => (ua: Promise<A>) => Promise<I> = curry2(chain);
// This fails because TS can't infer generics across the Curried2 polymorphic type.
// The more limited curry2 and curry3 functions work fine.
// export const chainCurry3 = ccurry2(chain);
export function apply<A, I>(
ua: Promise<A>,
ufai: Promise<(a: A) => I>,
): Promise<I> {
return Promise.all([ua, ufai]).then(([a, fai]) => fai(a));
}
export const applyCurry1 = curry2(apply);
const test1 = applyCurry1(Promise.resolve(1)); // (ufai: Promise<(n: number) => unknown>) => Promise<unknown>
const test2 = test1(Promise.resolve((n: number): string => "a".repeat(n))); // Promise<unknown>
test2.then(console.log);
// This fails because moving the generic throws a type mismatch
// export const applyCurry2: <A>(
// ua: Promise<A>,
// ) => <I>(ufai: Promise<(a: A) => I>) => Promise<I> = curry2(apply);
export function traverse<V extends Kind, A, I, J, K, L, M>(
A: Applicative<V>,
favi: (a: A) => $<V, [I, J, K], [L], [M]>,
ua: ReadonlyArray<A>,
): $<V, [ReadonlyArray<I>, J, K], [L], [M]> {
let out: $<V, [Array<I>, J, K], [L], [M]> = A.of([]);
let index = -1;
const length = ua.length;
const push = (is: I[]) => (i: I) => [...is, i];
while (++index < length) {
out = pipe(
out,
A.map(push),
A.ap(favi(ua[index])),
);
}
return out;
}
export const traverseCurry1 = curry3(traverse);
export const traverseCurry2: <V extends Kind, A, I, J, K, L, M>(
A: Applicative<V>,
) => (
favi: (a: A) => $<V, [I, J, K], [L], [M]>,
) => (ua: readonly A[]) => $<V, [readonly I[], J, K], [L], [M]> = curry3(
traverse,
);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment