rivo
Version:
🤖 The ultimate library you need for composable type-level programming in TypeScript, powered by HKT.
47 lines (43 loc) • 1.42 kB
TypeScript
import type { Monad, Monad$GetTypeClassW } from ".";
import type {
Args,
Call1W,
Call2W,
Fn1,
GenericFn,
GenericResolver,
GenericReturn1W,
Param0,
Return,
} from "../../HKT";
import type { Functor$GetTypeClassW } from "../Functor";
import type { HKT$Extract, HKT$GetConstruct, HKT$Mutate } from "../HKT";
/**
* Map a function over a {@link Monad} and flatten the result.
*
* Sig: `<F<~>, T, U>(f: (x: T) => F<U>, fa: F<T>) => F<U>`
*/
export type Chain<F extends Fn1<HKT$Extract<FA>, HKT$GetConstruct<FA>>, FA extends Monad> = Call1W<
Monad$GetTypeClassW<FA>["Flatten"],
Call2W<Functor$GetTypeClassW<FA>["Map"], F, FA>
>;
interface Resolver extends GenericResolver<[Fn1<never, Monad>, Monad], Monad> {
on1_: ([f]: Args<this>) => [[HKT$Mutate<Return<typeof f>, Param0<typeof f>>], Return<typeof f>];
on_1: ([, fa]: Args<this>) => [
[Fn1<HKT$Extract<typeof fa>, HKT$GetConstruct<typeof fa>>],
HKT$GetConstruct<typeof fa>,
];
on11: ([f, fa]: Args<this>) => [[], GenericReturn1W<typeof f, HKT$Extract<typeof fa>>];
}
/**
* [Fn] Map a function over a {@link Monad} and flatten the result.
*
* Sig: `<F<~>, T, U>(f: (x: T) => F<U>, fa: F<T>) => F<U>`
*/
export default interface ChainFn extends GenericFn<Resolver> {
def: ([f, fa]: Args<this>) => typeof f extends (
Fn1<HKT$Extract<typeof fa>, HKT$GetConstruct<typeof fa>>
) ?
Chain<typeof f, typeof fa>
: never;
}