-
Notifications
You must be signed in to change notification settings - Fork 7
/
mappable.ts
54 lines (50 loc) · 1.57 KB
/
mappable.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
/**
* 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<U extends Kind> extends Hold<U> {
readonly map: <A, I>(
fai: (value: A) => I,
) => <B = never, C = never, D = unknown, E = unknown>(
ta: $<U, [A, B, C], [D], [E]>,
) => $<U, [I, B, C], [D], [E]>;
}
/**
* The return type for the createBindTo function on Mappable. Useful to reduce
* type inference in documentation.
*
* @since 2.0.0
*/
export type BindTo<U extends Kind> = <N extends string>(
name: N,
) => <A, B = never, C = never, D = unknown, E = unknown>(
ua: $<U, [A, B, C], [D], [E]>,
) => $<U, [{ readonly [K in N]: A }, B, C], [D], [E]>;
/**
* 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.
*
* @since 2.0.0
*/
export function createBindTo<U extends Kind>(
{ map }: Mappable<U>,
): <N extends string>(
name: N,
) => <A, B = never, C = never, D = unknown, E = unknown>(
ua: $<U, [A, B, C], [D], [E]>,
) => $<U, [{ readonly [K in N]: A }, B, C], [D], [E]> {
// deno-lint-ignore no-explicit-any
return (name) => map((value) => ({ [name]: value }) as any);
}