/** * Mappable is a structure that allows a function to be applied inside of the * associated concrete structure. * * @module Mappable * @since 2.0.0 */ import type { $, Hold, Kind } from "./kind.ts"; /** * A Mappable structure has the method map. * * @since 2.0.0 */ export interface Mappable extends Hold { readonly map: ( fai: (value: A) => I, ) => ( ta: $, ) => $; } /** * The return type for the createBindTo function on Mappable. Useful to reduce * type inference in documentation. * * @since 2.0.0 */ export type BindTo = ( name: N, ) => ( ua: $, ) => $; /** * Create a bindTo function from a structure with an instance of Mappable. A * bindTo function takes the inner value of the structure and maps it to the * value of a struct with the given name. It is useful for lifting the value * such that it can then be used with a `bind` function, effectively allowing * for `Do`-like notation in typescript. * * @example * ```ts * import { createBindTo } from "./mappable.ts"; * import * as O from "./option.ts"; * import { pipe } from "./fn.ts"; * * const bindTo = createBindTo(O.MappableOption); * const option = O.some(5); * * const result = pipe( * option, * bindTo("value") * ); * * console.log(result); // Some({ value: 5 }) * ``` * * @since 2.0.0 */ export function createBindTo( { map }: Mappable, ): ( name: N, ) => ( ua: $, ) => $ { // deno-lint-ignore no-explicit-any return (name) => map((value) => ({ [name]: value }) as any); }