import { dual } from "../Function.ts" import type { Kind, TypeLambda } from "../HKT.ts" import type { NoInfer } from "../Types.ts" interface Map { ( f: (a: A) => B ): (self: Kind) => Kind ( self: Kind, f: (a: A) => B ): Kind } interface FlatMap { ( f: (a: A) => Kind ): ( self: Kind ) => Kind ( self: Kind, f: (a: A) => Kind ): Kind } /** @internal */ export const let_ = ( map: Map ): { ( name: Exclude, f: (a: NoInfer) => B ): ( self: Kind ) => Kind ( self: Kind, name: Exclude, f: (a: NoInfer) => B ): Kind } => dual( 3, ( self: Kind, name: Exclude, f: (a: NoInfer) => B ): Kind => map(self, (a) => ({ ...a, [name]: f(a) }) as any) ) /** @internal */ export const bindTo = ( map: Map ): { ( name: N ): ( self: Kind ) => Kind> ( self: Kind, name: N ): Kind> } => dual( 2, ( self: Kind, name: N ): Kind> => map(self, (a) => ({ [name]: a }) as Record) ) /** @internal */ export const bind = ( map: Map, flatMap: FlatMap ): { ( name: Exclude, f: (a: NoInfer) => Kind ): ( self: Kind ) => Kind< F, R1 & R2, O1 | O2, E1 | E2, { [K in keyof A | N]: K extends keyof A ? A[K] : B } > ( self: Kind, name: Exclude, f: (a: NoInfer) => Kind ): Kind< F, R1 & R2, O1 | O2, E1 | E2, { [K in keyof A | N]: K extends keyof A ? A[K] : B } > } => dual( 3, ( self: Kind, name: Exclude, f: (a: NoInfer) => Kind ): Kind< F, R1 & R2, O1 | O2, E1 | E2, { [K in keyof A | N]: K extends keyof A ? A[K] : B } > => flatMap(self, (a) => map(f(a), (b) => ({ ...a, [name]: b }) as any)) )