Last active
January 4, 2023 18:35
-
-
Save baetheus/11e3c6d9a0497dd53b3a17fe7459a8be to your computer and use it in GitHub Desktop.
Testing Deno Doc Gen
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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