import { dual } from "../Function.js" import type { Kind, TypeLambda } from "../HKT.js" import type { NoInfer } from "../Types.js" type Map = { (f: (a: A) => B): (self: Kind) => Kind (self: Kind, f: (a: A) => B): Kind } type 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 { [K in N]: A }))) /** @internal */ export const bind = (map: Map, flatMap: FlatMap): { ( name: Exclude, f: (a: NoInfer) => Kind ): ( self: Kind ) => Kind ( self: Kind, name: Exclude, f: (a: NoInfer) => Kind ): Kind } => dual(3, ( self: Kind, name: Exclude, f: (a: NoInfer) => Kind ): Kind => flatMap( self, (a) => map(f(a), (b) => ({ ...a, [name]: b }) as { [K in keyof A | N]: K extends keyof A ? A[K] : B }) ))