kind-adt 0.2.0 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +90 -1
- package/index.d.ts +93 -16
- package/index.js +55 -20
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -597,12 +597,101 @@ import { show } from "showify";
|
|
|
597
597
|
export function println(...args: unknown[]) {
|
|
598
598
|
console.log(
|
|
599
599
|
...args.map((arg) =>
|
|
600
|
-
typeof arg === "string" ? arg : show(arg, { colors: true, trailingComma: "
|
|
600
|
+
typeof arg === "string" ? arg : show(arg, { colors: true, trailingComma: "auto", indent: 2 }),
|
|
601
601
|
),
|
|
602
602
|
);
|
|
603
603
|
}
|
|
604
604
|
```
|
|
605
605
|
|
|
606
|
+
### Add your own methods to ADTs
|
|
607
|
+
|
|
608
|
+
> [!WARNING]
|
|
609
|
+
>
|
|
610
|
+
> This feature is not recommended for most users, as it may lead to unexpected behavior while module resolution. Use it at your own risk.
|
|
611
|
+
|
|
612
|
+
ADTs and ADT constructors in kind-adt use a prototype chain to provide “methods” like `.pipe()`. Due to the nature of how prototypes work in JavaScript, you can add your own methods (or “[monkey patch](https://en.wikipedia.org/wiki/Monkey_patch)”) to ADTs or ADT constructors by modifying the prototype of the ADT or ADT constructor.
|
|
613
|
+
|
|
614
|
+
kind-adt exports four prototypes for you to use, including the `PipeableProto` mentioned in the [Functional pipelines with `.pipe()`](#functional-pipelines-with-pipe) section:
|
|
615
|
+
|
|
616
|
+
```typescript
|
|
617
|
+
import {
|
|
618
|
+
type Pipeable,
|
|
619
|
+
PipeableProto,
|
|
620
|
+
type PipeableFunction,
|
|
621
|
+
PipeableFunctionProto,
|
|
622
|
+
type ADT,
|
|
623
|
+
ADTProto,
|
|
624
|
+
type ADTConstructor,
|
|
625
|
+
ADTConstructorProto,
|
|
626
|
+
} from "kind-adt";
|
|
627
|
+
```
|
|
628
|
+
|
|
629
|
+
Each `XxxProto` has a related `Xxx` type, which is the type of the object that can be created from the prototype. ADTs and ADT constructors in kind-adt follow the following prototype chain:
|
|
630
|
+
|
|
631
|
+
```typescript
|
|
632
|
+
╔══════════════════════════════════╗ ╔════════════╗ ╔═════════════════╗
|
|
633
|
+
║ Concrete ADT (e.g., `Some(...)`) ║ ← ║ `ADTProto` ║ ← ║ `PipeableProto` ║
|
|
634
|
+
╚══════════════════════════════════╝ ╚════════════╝ ╚═════════════════╝
|
|
635
|
+
|
|
636
|
+
╔═════════════════════════════════════════╗ ╔═══════════════════════╗ ╔═════════════════════════╗
|
|
637
|
+
║ Concrete ADT constructor (e.g., `None`) ║ ← ║ `ADTConstructorProto` ║ ← ║ `PipeableFunctionProto` ║
|
|
638
|
+
╚═════════════════════════════════════════╝ ╚═══════════════════════╝ ╚═════════════════════════╝
|
|
639
|
+
```
|
|
640
|
+
|
|
641
|
+
Note that though ADTs and ADT constructors share the same `.pipe()` method, they actually have independent prototype chains. This means that you have to patch both prototypes if you want to add your own methods to both ADTs and ADT constructors.
|
|
642
|
+
|
|
643
|
+
The following example shows how to add a `.println()` method to add ADTs and ADT constructors with type safety. We’ll create a `patches.ts` file to add the method to the prototypes of ADTs and ADT constructors.
|
|
644
|
+
|
|
645
|
+
```typescript
|
|
646
|
+
// patches.ts
|
|
647
|
+
import { type ADT, ADTProto, type ADTConstructor, ADTConstructorProto } from "kind-adt";
|
|
648
|
+
import { show } from "showify";
|
|
649
|
+
|
|
650
|
+
/* Make TypeScript aware of the new method with a module augmentation
|
|
651
|
+
https://www.typescriptlang.org/docs/handbook/declaration-merging.html#module-augmentation */
|
|
652
|
+
declare module "kind-adt" {
|
|
653
|
+
interface ADT {
|
|
654
|
+
println(): void;
|
|
655
|
+
}
|
|
656
|
+
|
|
657
|
+
interface ADTConstructor {
|
|
658
|
+
println(): void;
|
|
659
|
+
}
|
|
660
|
+
}
|
|
661
|
+
|
|
662
|
+
/* Add the method to the ADT prototype */
|
|
663
|
+
ADTProto.println = function println(this: ADT) {
|
|
664
|
+
console.log(show(this, { colors: true, trailingComma: "auto", indent: 2 }));
|
|
665
|
+
};
|
|
666
|
+
ADTConstructorProto.println = function println(this: ADTConstructor) {
|
|
667
|
+
console.log(show(this, { colors: true, trailingComma: "auto", indent: 2 }));
|
|
668
|
+
};
|
|
669
|
+
|
|
670
|
+
/* Ensure TypeScript treats this file as a module */
|
|
671
|
+
export {};
|
|
672
|
+
```
|
|
673
|
+
|
|
674
|
+
Then you can import the `patches.ts` file in your main file to apply the patches:
|
|
675
|
+
|
|
676
|
+
```typescript
|
|
677
|
+
import "./patches"; // Import the patches file
|
|
678
|
+
|
|
679
|
+
import { type Data, make } from "kind-adt";
|
|
680
|
+
|
|
681
|
+
type Option<T> = Data<{
|
|
682
|
+
Some: [value: T];
|
|
683
|
+
None: [];
|
|
684
|
+
}>;
|
|
685
|
+
|
|
686
|
+
const { Some, None } = make<OptionHKT>();
|
|
687
|
+
interface OptionHKT extends HKT {
|
|
688
|
+
return: Option<Arg0<this>>;
|
|
689
|
+
}
|
|
690
|
+
|
|
691
|
+
Some(42).println(); // Prints: Some(42)
|
|
692
|
+
None.println(); // Prints: None
|
|
693
|
+
```
|
|
694
|
+
|
|
606
695
|
## FAQ
|
|
607
696
|
|
|
608
697
|
### I don’t want to install another package for HKT. Can I implement my own?
|
package/index.d.ts
CHANGED
|
@@ -126,12 +126,89 @@ export interface Pipeable {
|
|
|
126
126
|
// prettier-ignore
|
|
127
127
|
pipe<A, B = never, C = never, D = never, E = never, F = never, G = never, H = never, I = never, J = never, K = never, L = never, M = never, N = never, O = never, P = never, Q = never, R = never, S = never, T = never, U = never, V = never, W = never, X = never, Y = never, Z = never>(this: A, ab: (a: A) => B, bc: (b: B) => C, cd: (c: C) => D, de: (d: D) => E, ef: (e: E) => F, fg: (f: F) => G, gh: (g: G) => H, hi: (h: H) => I, ij: (i: I) => J, jk: (j: J) => K, kl: (k: K) => L, lm: (l: L) => M, mn: (m: M) => N, no: (n: N) => O, op: (o: O) => P, pq: (p: P) => Q, qr: (q: Q) => R, rs: (r: R) => S, st: (s: S) => T, tu: (t: T) => U, uv: (u: U) => V, vw: (v: V) => W, wx: (w: W) => X, xy: (x: X) => Y, yz: (y: Y) => Z): Z;
|
|
128
128
|
}
|
|
129
|
-
|
|
130
|
-
/**
|
|
131
|
-
* The prototype to build a {@linkcode Pipeable} object.
|
|
132
|
-
*/
|
|
129
|
+
/** The prototype to build a {@linkcode Pipeable} object. */
|
|
133
130
|
export const PipeableProto: Pipeable;
|
|
134
131
|
|
|
132
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-function-type
|
|
133
|
+
export interface PipeableFunction extends Function {
|
|
134
|
+
/**
|
|
135
|
+
* Pipe the value through a series of functions.
|
|
136
|
+
*
|
|
137
|
+
* **Example**
|
|
138
|
+
*
|
|
139
|
+
* ```typescript
|
|
140
|
+
* import { type Data, make } from "kind-adt";
|
|
141
|
+
*
|
|
142
|
+
* type BoxNumber = Data<{
|
|
143
|
+
* Box: [number];
|
|
144
|
+
* }>;
|
|
145
|
+
* const { Box } = make<BoxNumber>();
|
|
146
|
+
*
|
|
147
|
+
* Box(42).pipe((box) => box._0 + 1, (n) => n * 2, (n) => n.toString()); // => "86"
|
|
148
|
+
* ```
|
|
149
|
+
*/
|
|
150
|
+
pipe<A>(this: A): A;
|
|
151
|
+
pipe<A, B = never>(this: A, ab: (a: A) => B): B;
|
|
152
|
+
// prettier-ignore
|
|
153
|
+
pipe<A, B = never, C = never>(this: A, ab: (a: A) => B, bc: (b: B) => C): C;
|
|
154
|
+
// prettier-ignore
|
|
155
|
+
pipe<A, B = never, C = never, D = never>(this: A, ab: (a: A) => B, bc: (b: B) => C, cd: (c: C) => D): D;
|
|
156
|
+
// prettier-ignore
|
|
157
|
+
pipe<A, B = never, C = never, D = never, E = never>(this: A, ab: (a: A) => B, bc: (b: B) => C, cd: (c: C) => D, de: (d: D) => E): E;
|
|
158
|
+
// prettier-ignore
|
|
159
|
+
pipe<A, B = never, C = never, D = never, E = never, F = never>(this: A, ab: (a: A) => B, bc: (b: B) => C, cd: (c: C) => D, de: (d: D) => E, ef: (e: E) => F): F;
|
|
160
|
+
// prettier-ignore
|
|
161
|
+
pipe<A, B = never, C = never, D = never, E = never, F = never, G = never>(this: A, ab: (a: A) => B, bc: (b: B) => C, cd: (c: C) => D, de: (d: D) => E, ef: (e: E) => F, fg: (f: F) => G): G;
|
|
162
|
+
// prettier-ignore
|
|
163
|
+
pipe<A, B = never, C = never, D = never, E = never, F = never, G = never, H = never>(this: A, ab: (a: A) => B, bc: (b: B) => C, cd: (c: C) => D, de: (d: D) => E, ef: (e: E) => F, fg: (f: F) => G, gh: (g: G) => H): H;
|
|
164
|
+
// prettier-ignore
|
|
165
|
+
pipe<A, B = never, C = never, D = never, E = never, F = never, G = never, H = never, I = never>(this: A, ab: (a: A) => B, bc: (b: B) => C, cd: (c: C) => D, de: (d: D) => E, ef: (e: E) => F, fg: (f: F) => G, gh: (g: G) => H, hi: (h: H) => I): I;
|
|
166
|
+
// prettier-ignore
|
|
167
|
+
pipe<A, B = never, C = never, D = never, E = never, F = never, G = never, H = never, I = never, J = never>(this: A, ab: (a: A) => B, bc: (b: B) => C, cd: (c: C) => D, de: (d: D) => E, ef: (e: E) => F, fg: (f: F) => G, gh: (g: G) => H, hi: (h: H) => I, ij: (i: I) => J): J;
|
|
168
|
+
// prettier-ignore
|
|
169
|
+
pipe<A, B = never, C = never, D = never, E = never, F = never, G = never, H = never, I = never, J = never, K = never>(this: A, ab: (a: A) => B, bc: (b: B) => C, cd: (c: C) => D, de: (d: D) => E, ef: (e: E) => F, fg: (f: F) => G, gh: (g: G) => H, hi: (h: H) => I, ij: (i: I) => J, jk: (j: J) => K): K;
|
|
170
|
+
// prettier-ignore
|
|
171
|
+
pipe<A, B = never, C = never, D = never, E = never, F = never, G = never, H = never, I = never, J = never, K = never, L = never>(this: A, ab: (a: A) => B, bc: (b: B) => C, cd: (c: C) => D, de: (d: D) => E, ef: (e: E) => F, fg: (f: F) => G, gh: (g: G) => H, hi: (h: H) => I, ij: (i: I) => J, jk: (j: J) => K, kl: (k: K) => L): L;
|
|
172
|
+
// prettier-ignore
|
|
173
|
+
pipe<A, B = never, C = never, D = never, E = never, F = never, G = never, H = never, I = never, J = never, K = never, L = never, M = never>(this: A, ab: (a: A) => B, bc: (b: B) => C, cd: (c: C) => D, de: (d: D) => E, ef: (e: E) => F, fg: (f: F) => G, gh: (g: G) => H, hi: (h: H) => I, ij: (i: I) => J, jk: (j: J) => K, kl: (k: K) => L, lm: (l: L) => M): M;
|
|
174
|
+
// prettier-ignore
|
|
175
|
+
pipe<A, B = never, C = never, D = never, E = never, F = never, G = never, H = never, I = never, J = never, K = never, L = never, M = never, N = never>(this: A, ab: (a: A) => B, bc: (b: B) => C, cd: (c: C) => D, de: (d: D) => E, ef: (e: E) => F, fg: (f: F) => G, gh: (g: G) => H, hi: (h: H) => I, ij: (i: I) => J, jk: (j: J) => K, kl: (k: K) => L, lm: (l: L) => M, mn: (m: M) => N): N;
|
|
176
|
+
// prettier-ignore
|
|
177
|
+
pipe<A, B = never, C = never, D = never, E = never, F = never, G = never, H = never, I = never, J = never, K = never, L = never, M = never, N = never, O = never>(this: A, ab: (a: A) => B, bc: (b: B) => C, cd: (c: C) => D, de: (d: D) => E, ef: (e: E) => F, fg: (f: F) => G, gh: (g: G) => H, hi: (h: H) => I, ij: (i: I) => J, jk: (j: J) => K, kl: (k: K) => L, lm: (l: L) => M, mn: (m: M) => N, no: (n: N) => O): O;
|
|
178
|
+
// prettier-ignore
|
|
179
|
+
pipe<A, B = never, C = never, D = never, E = never, F = never, G = never, H = never, I = never, J = never, K = never, L = never, M = never, N = never, O = never, P = never>(this: A, ab: (a: A) => B, bc: (b: B) => C, cd: (c: C) => D, de: (d: D) => E, ef: (e: E) => F, fg: (f: F) => G, gh: (g: G) => H, hi: (h: H) => I, ij: (i: I) => J, jk: (j: J) => K, kl: (k: K) => L, lm: (l: L) => M, mn: (m: M) => N, no: (n: N) => O, op: (o: O) => P): P;
|
|
180
|
+
// prettier-ignore
|
|
181
|
+
pipe<A, B = never, C = never, D = never, E = never, F = never, G = never, H = never, I = never, J = never, K = never, L = never, M = never, N = never, O = never, P = never, Q = never>(this: A, ab: (a: A) => B, bc: (b: B) => C, cd: (c: C) => D, de: (d: D) => E, ef: (e: E) => F, fg: (f: F) => G, gh: (g: G) => H, hi: (h: H) => I, ij: (i: I) => J, jk: (j: J) => K, kl: (k: K) => L, lm: (l: L) => M, mn: (m: M) => N, no: (n: N) => O, op: (o: O) => P, pq: (p: P) => Q): Q;
|
|
182
|
+
// prettier-ignore
|
|
183
|
+
pipe<A, B = never, C = never, D = never, E = never, F = never, G = never, H = never, I = never, J = never, K = never, L = never, M = never, N = never, O = never, P = never, Q = never, R = never>(this: A, ab: (a: A) => B, bc: (b: B) => C, cd: (c: C) => D, de: (d: D) => E, ef: (e: E) => F, fg: (f: F) => G, gh: (g: G) => H, hi: (h: H) => I, ij: (i: I) => J, jk: (j: J) => K, kl: (k: K) => L, lm: (l: L) => M, mn: (m: M) => N, no: (n: N) => O, op: (o: O) => P, pq: (p: P) => Q, qr: (q: Q) => R): R;
|
|
184
|
+
// prettier-ignore
|
|
185
|
+
pipe<A, B = never, C = never, D = never, E = never, F = never, G = never, H = never, I = never, J = never, K = never, L = never, M = never, N = never, O = never, P = never, Q = never, R = never, S = never>(this: A, ab: (a: A) => B, bc: (b: B) => C, cd: (c: C) => D, de: (d: D) => E, ef: (e: E) => F, fg: (f: F) => G, gh: (g: G) => H, hi: (h: H) => I, ij: (i: I) => J, jk: (j: J) => K, kl: (k: K) => L, lm: (l: L) => M, mn: (m: M) => N, no: (n: N) => O, op: (o: O) => P, pq: (p: P) => Q, qr: (q: Q) => R, rs: (r: R) => S): S;
|
|
186
|
+
// prettier-ignore
|
|
187
|
+
pipe<A, B = never, C = never, D = never, E = never, F = never, G = never, H = never, I = never, J = never, K = never, L = never, M = never, N = never, O = never, P = never, Q = never, R = never, S = never, T = never>(this: A, ab: (a: A) => B, bc: (b: B) => C, cd: (c: C) => D, de: (d: D) => E, ef: (e: E) => F, fg: (f: F) => G, gh: (g: G) => H, hi: (h: H) => I, ij: (i: I) => J, jk: (j: J) => K, kl: (k: K) => L, lm: (l: L) => M, mn: (m: M) => N, no: (n: N) => O, op: (o: O) => P, pq: (p: P) => Q, qr: (q: Q) => R, rs: (r: R) => S, st: (s: S) => T): T;
|
|
188
|
+
// prettier-ignore
|
|
189
|
+
pipe<A, B = never, C = never, D = never, E = never, F = never, G = never, H = never, I = never, J = never, K = never, L = never, M = never, N = never, O = never, P = never, Q = never, R = never, S = never, T = never, U = never>(this: A, ab: (a: A) => B, bc: (b: B) => C, cd: (c: C) => D, de: (d: D) => E, ef: (e: E) => F, fg: (f: F) => G, gh: (g: G) => H, hi: (h: H) => I, ij: (i: I) => J, jk: (j: J) => K, kl: (k: K) => L, lm: (l: L) => M, mn: (m: M) => N, no: (n: N) => O, op: (o: O) => P, pq: (p: P) => Q, qr: (q: Q) => R, rs: (r: R) => S, st: (s: S) => T, tu: (t: T) => U): U;
|
|
190
|
+
// prettier-ignore
|
|
191
|
+
pipe<A, B = never, C = never, D = never, E = never, F = never, G = never, H = never, I = never, J = never, K = never, L = never, M = never, N = never, O = never, P = never, Q = never, R = never, S = never, T = never, U = never, V = never>(this: A, ab: (a: A) => B, bc: (b: B) => C, cd: (c: C) => D, de: (d: D) => E, ef: (e: E) => F, fg: (f: F) => G, gh: (g: G) => H, hi: (h: H) => I, ij: (i: I) => J, jk: (j: J) => K, kl: (k: K) => L, lm: (l: L) => M, mn: (m: M) => N, no: (n: N) => O, op: (o: O) => P, pq: (p: P) => Q, qr: (q: Q) => R, rs: (r: R) => S, st: (s: S) => T, tu: (t: T) => U, uv: (u: U) => V): V;
|
|
192
|
+
// prettier-ignore
|
|
193
|
+
pipe<A, B = never, C = never, D = never, E = never, F = never, G = never, H = never, I = never, J = never, K = never, L = never, M = never, N = never, O = never, P = never, Q = never, R = never, S = never, T = never, U = never, V = never, W = never>(this: A, ab: (a: A) => B, bc: (b: B) => C, cd: (c: C) => D, de: (d: D) => E, ef: (e: E) => F, fg: (f: F) => G, gh: (g: G) => H, hi: (h: H) => I, ij: (i: I) => J, jk: (j: J) => K, kl: (k: K) => L, lm: (l: L) => M, mn: (m: M) => N, no: (n: N) => O, op: (o: O) => P, pq: (p: P) => Q, qr: (q: Q) => R, rs: (r: R) => S, st: (s: S) => T, tu: (t: T) => U, uv: (u: U) => V, vw: (v: V) => W): W;
|
|
194
|
+
// prettier-ignore
|
|
195
|
+
pipe<A, B = never, C = never, D = never, E = never, F = never, G = never, H = never, I = never, J = never, K = never, L = never, M = never, N = never, O = never, P = never, Q = never, R = never, S = never, T = never, U = never, V = never, W = never, X = never>(this: A, ab: (a: A) => B, bc: (b: B) => C, cd: (c: C) => D, de: (d: D) => E, ef: (e: E) => F, fg: (f: F) => G, gh: (g: G) => H, hi: (h: H) => I, ij: (i: I) => J, jk: (j: J) => K, kl: (k: K) => L, lm: (l: L) => M, mn: (m: M) => N, no: (n: N) => O, op: (o: O) => P, pq: (p: P) => Q, qr: (q: Q) => R, rs: (r: R) => S, st: (s: S) => T, tu: (t: T) => U, uv: (u: U) => V, vw: (v: V) => W, wx: (w: W) => X): X;
|
|
196
|
+
// prettier-ignore
|
|
197
|
+
pipe<A, B = never, C = never, D = never, E = never, F = never, G = never, H = never, I = never, J = never, K = never, L = never, M = never, N = never, O = never, P = never, Q = never, R = never, S = never, T = never, U = never, V = never, W = never, X = never, Y = never>(this: A, ab: (a: A) => B, bc: (b: B) => C, cd: (c: C) => D, de: (d: D) => E, ef: (e: E) => F, fg: (f: F) => G, gh: (g: G) => H, hi: (h: H) => I, ij: (i: I) => J, jk: (j: J) => K, kl: (k: K) => L, lm: (l: L) => M, mn: (m: M) => N, no: (n: N) => O, op: (o: O) => P, pq: (p: P) => Q, qr: (q: Q) => R, rs: (r: R) => S, st: (s: S) => T, tu: (t: T) => U, uv: (u: U) => V, vw: (v: V) => W, wx: (w: W) => X, xy: (x: X) => Y): Y;
|
|
198
|
+
// prettier-ignore
|
|
199
|
+
pipe<A, B = never, C = never, D = never, E = never, F = never, G = never, H = never, I = never, J = never, K = never, L = never, M = never, N = never, O = never, P = never, Q = never, R = never, S = never, T = never, U = never, V = never, W = never, X = never, Y = never, Z = never>(this: A, ab: (a: A) => B, bc: (b: B) => C, cd: (c: C) => D, de: (d: D) => E, ef: (e: E) => F, fg: (f: F) => G, gh: (g: G) => H, hi: (h: H) => I, ij: (i: I) => J, jk: (j: J) => K, kl: (k: K) => L, lm: (l: L) => M, mn: (m: M) => N, no: (n: N) => O, op: (o: O) => P, pq: (p: P) => Q, qr: (q: Q) => R, rs: (r: R) => S, st: (s: S) => T, tu: (t: T) => U, uv: (u: U) => V, vw: (v: V) => W, wx: (w: W) => X, xy: (x: X) => Y, yz: (y: Y) => Z): Z;
|
|
200
|
+
}
|
|
201
|
+
/** The prototype to build a {@linkcode PipeableFunction}. */
|
|
202
|
+
export const PipeableFunctionProto: PipeableFunction;
|
|
203
|
+
|
|
204
|
+
export interface ADT extends Pipeable {}
|
|
205
|
+
/** The prototype of ADTs. */
|
|
206
|
+
export const ADTProto: ADT;
|
|
207
|
+
|
|
208
|
+
export interface ADTConstructor extends PipeableFunction {}
|
|
209
|
+
/** The prototype of ADT constructors. */
|
|
210
|
+
export const ADTConstructorProto: ADTConstructor;
|
|
211
|
+
|
|
135
212
|
/**************
|
|
136
213
|
* Main types *
|
|
137
214
|
**************/
|
|
@@ -172,7 +249,7 @@ export type Tagged<
|
|
|
172
249
|
{ readonly [I in IndexOf<Fields> as `_${I}`]: Fields[I] }
|
|
173
250
|
: never
|
|
174
251
|
> &
|
|
175
|
-
|
|
252
|
+
ADT;
|
|
176
253
|
|
|
177
254
|
/**
|
|
178
255
|
* Create an ADT with tagged types.
|
|
@@ -382,16 +459,16 @@ export type Constructor<
|
|
|
382
459
|
[Type] extends (
|
|
383
460
|
[Tagged] // Non-generic ADT
|
|
384
461
|
) ?
|
|
385
|
-
{ readonly _tag: Tag } &
|
|
462
|
+
{ readonly _tag: Tag } & ADT &
|
|
386
463
|
((...args: ExtractFields<Extract<Type, Tagged<Tag>>>) => Type)
|
|
387
464
|
: // Generic ADT
|
|
388
465
|
Type extends TypeLambda<[never], unknown> ?
|
|
389
466
|
unknown extends _UpperBound<HKTParams<Type>[0]> ?
|
|
390
|
-
{ readonly _tag: Tag } &
|
|
467
|
+
{ readonly _tag: Tag } & ADT &
|
|
391
468
|
(<T = never>(
|
|
392
469
|
...args: ExtractFields<FilterTagged<ApplyHKT<Type, [T]>, Tag>>
|
|
393
470
|
) => ApplyHKT<Type, [T]>)
|
|
394
|
-
: { readonly _tag: Tag } &
|
|
471
|
+
: { readonly _tag: Tag } & ADT &
|
|
395
472
|
(<T extends _UpperBound<HKTParams<Type>[0]> = never>(
|
|
396
473
|
...args: ExtractFields<FilterTagged<ApplyHKT<Type, [T]>, Tag>>
|
|
397
474
|
) => ApplyHKT<Type, [T]>)
|
|
@@ -399,21 +476,21 @@ export type Constructor<
|
|
|
399
476
|
[unknown, unknown] extends (
|
|
400
477
|
[_UpperBound<HKTParams<Type>[0]>, _UpperBound<HKTParams<Type>[1]>]
|
|
401
478
|
) ?
|
|
402
|
-
{ readonly _tag: Tag } &
|
|
479
|
+
{ readonly _tag: Tag } & ADT &
|
|
403
480
|
(<T = never, U = never>(
|
|
404
481
|
...args: ExtractFields<FilterTagged<ApplyHKT<Type, [T, U]>, Tag>>
|
|
405
482
|
) => ApplyHKT<Type, [T, U]>)
|
|
406
483
|
: unknown extends _UpperBound<HKTParams<Type>[0]> ?
|
|
407
|
-
{ readonly _tag: Tag } &
|
|
484
|
+
{ readonly _tag: Tag } & ADT &
|
|
408
485
|
(<T = never, U extends _UpperBound<HKTParams<Type>[1]> = never>(
|
|
409
486
|
...args: ExtractFields<FilterTagged<ApplyHKT<Type, [T, U]>, Tag>>
|
|
410
487
|
) => ApplyHKT<Type, [T, U]>)
|
|
411
488
|
: unknown extends _UpperBound<HKTParams<Type>[1]> ?
|
|
412
|
-
{ readonly _tag: Tag } &
|
|
489
|
+
{ readonly _tag: Tag } & ADT &
|
|
413
490
|
(<T extends _UpperBound<HKTParams<Type>[0]> = never, U = never>(
|
|
414
491
|
...args: ExtractFields<FilterTagged<ApplyHKT<Type, [T, U]>, Tag>>
|
|
415
492
|
) => ApplyHKT<Type, [T, U]>)
|
|
416
|
-
: { readonly _tag: Tag } &
|
|
493
|
+
: { readonly _tag: Tag } & ADT &
|
|
417
494
|
(<
|
|
418
495
|
T extends _UpperBound<HKTParams<Type>[0]> = never,
|
|
419
496
|
U extends _UpperBound<HKTParams<Type>[1]> = never,
|
|
@@ -421,7 +498,7 @@ export type Constructor<
|
|
|
421
498
|
...args: ExtractFields<FilterTagged<ApplyHKT<Type, [T, U]>, Tag>>
|
|
422
499
|
) => ApplyHKT<Type, [T, U]>)
|
|
423
500
|
: Type extends TypeLambda<[never, never, never], unknown> ?
|
|
424
|
-
{ readonly _tag: Tag } &
|
|
501
|
+
{ readonly _tag: Tag } & ADT &
|
|
425
502
|
(<
|
|
426
503
|
T extends _UpperBound<HKTParams<Type>[0]> = never,
|
|
427
504
|
U extends _UpperBound<HKTParams<Type>[1]> = never,
|
|
@@ -430,7 +507,7 @@ export type Constructor<
|
|
|
430
507
|
...args: ExtractFields<FilterTagged<ApplyHKT<Type, [T, U, V]>, Tag>>
|
|
431
508
|
) => ApplyHKT<Type, [T, U, V]>)
|
|
432
509
|
: Type extends TypeLambda<[never, never, never, never], unknown> ?
|
|
433
|
-
{ readonly _tag: Tag } &
|
|
510
|
+
{ readonly _tag: Tag } & ADT &
|
|
434
511
|
(<
|
|
435
512
|
T extends _UpperBound<HKTParams<Type>[0]> = never,
|
|
436
513
|
U extends _UpperBound<HKTParams<Type>[1]> = never,
|
|
@@ -440,7 +517,7 @@ export type Constructor<
|
|
|
440
517
|
...args: ExtractFields<FilterTagged<ApplyHKT<Type, [T, U, V, W]>, Tag>>
|
|
441
518
|
) => ApplyHKT<Type, [T, U, V, W]>)
|
|
442
519
|
: Type extends TypeLambda<[never, never, never, never, never], unknown> ?
|
|
443
|
-
{ readonly _tag: Tag } &
|
|
520
|
+
{ readonly _tag: Tag } & ADT &
|
|
444
521
|
(<
|
|
445
522
|
T extends _UpperBound<HKTParams<Type>[0]> = never,
|
|
446
523
|
U extends _UpperBound<HKTParams<Type>[1]> = never,
|
|
@@ -455,7 +532,7 @@ export type Constructor<
|
|
|
455
532
|
: Type extends (
|
|
456
533
|
TypeLambda<[never, never, never, never, never, never], unknown>
|
|
457
534
|
) ?
|
|
458
|
-
{ readonly _tag: Tag } &
|
|
535
|
+
{ readonly _tag: Tag } & ADT &
|
|
459
536
|
(<
|
|
460
537
|
T extends _UpperBound<HKTParams<Type>[0]> = never,
|
|
461
538
|
U extends _UpperBound<HKTParams<Type>[1]> = never,
|
package/index.js
CHANGED
|
@@ -36,11 +36,7 @@ export function make(variants) {
|
|
|
36
36
|
for (let i = 0; i < args.length; i++) result["_" + i] = args[i];
|
|
37
37
|
return result;
|
|
38
38
|
}, tag),
|
|
39
|
-
{
|
|
40
|
-
_tag: tag,
|
|
41
|
-
toJSON: () => ({ _tag: tag }),
|
|
42
|
-
[Symbol.for("nodejs.util.inspect.custom")]: () => ({ _tag: tag }),
|
|
43
|
-
}
|
|
39
|
+
{ _tag: tag }
|
|
44
40
|
),
|
|
45
41
|
ADTConstructorProto
|
|
46
42
|
);
|
|
@@ -394,6 +390,29 @@ function inspect({ ancestors, c, level }, expand) {
|
|
|
394
390
|
body = body.values[2];
|
|
395
391
|
}
|
|
396
392
|
|
|
393
|
+
let shouldCollapse = false;
|
|
394
|
+
let firstFieldNode;
|
|
395
|
+
if (fields.length === 1) {
|
|
396
|
+
firstFieldNode = expand(fields[0]);
|
|
397
|
+
shouldCollapse =
|
|
398
|
+
firstFieldNode.type === "between" ||
|
|
399
|
+
(firstFieldNode.type === "variant" &&
|
|
400
|
+
firstFieldNode.inline.type === "between" &&
|
|
401
|
+
firstFieldNode.wrap.type === "between") ||
|
|
402
|
+
(firstFieldNode.type === "sequence" &&
|
|
403
|
+
firstFieldNode.values.slice(0, -1).every((v) => v.type === "text") &&
|
|
404
|
+
firstFieldNode.values[firstFieldNode.values.length - 1].type ===
|
|
405
|
+
"between") ||
|
|
406
|
+
(firstFieldNode.type === "sequence" &&
|
|
407
|
+
firstFieldNode.values.slice(0, -1).every((v) => v.type === "text") &&
|
|
408
|
+
firstFieldNode.values[firstFieldNode.values.length - 1].type ===
|
|
409
|
+
"variant" &&
|
|
410
|
+
firstFieldNode.values[firstFieldNode.values.length - 1].inline.type ===
|
|
411
|
+
"between" &&
|
|
412
|
+
firstFieldNode.values[firstFieldNode.values.length - 1].wrap.type ===
|
|
413
|
+
"between");
|
|
414
|
+
}
|
|
415
|
+
|
|
397
416
|
return (
|
|
398
417
|
fields.length ?
|
|
399
418
|
variant(
|
|
@@ -405,17 +424,25 @@ function inspect({ ancestors, c, level }, expand) {
|
|
|
405
424
|
...(body.type === "text" ? [text(")")] : [text(") "), body]),
|
|
406
425
|
]),
|
|
407
426
|
body.type === "text" ?
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
text(")")
|
|
412
|
-
)
|
|
413
|
-
: pair(
|
|
414
|
-
between(
|
|
427
|
+
shouldCollapse ?
|
|
428
|
+
sequence([text(c.cyan(this._tag) + "("), firstFieldNode, text(")")])
|
|
429
|
+
: between(
|
|
415
430
|
fields.map((field) => pair(expand(field), text(","))),
|
|
416
431
|
text(c.cyan(this._tag) + "("),
|
|
417
|
-
text(")
|
|
418
|
-
)
|
|
432
|
+
text(")")
|
|
433
|
+
)
|
|
434
|
+
: pair(
|
|
435
|
+
shouldCollapse ?
|
|
436
|
+
sequence([
|
|
437
|
+
text(c.cyan(this._tag) + "("),
|
|
438
|
+
firstFieldNode,
|
|
439
|
+
text(") "),
|
|
440
|
+
])
|
|
441
|
+
: between(
|
|
442
|
+
fields.map((field) => pair(expand(field), text(","))),
|
|
443
|
+
text(c.cyan(this._tag) + "("),
|
|
444
|
+
text(") ")
|
|
445
|
+
),
|
|
419
446
|
body
|
|
420
447
|
)
|
|
421
448
|
)
|
|
@@ -470,10 +497,18 @@ export const PipeableProto = {
|
|
|
470
497
|
},
|
|
471
498
|
};
|
|
472
499
|
|
|
473
|
-
const
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
500
|
+
export const PipeableFunctionProto = { ...PipeableProto };
|
|
501
|
+
Object.setPrototypeOf(PipeableFunctionProto, Function.prototype);
|
|
502
|
+
|
|
503
|
+
export const ADTProto = Object.create(PipeableProto);
|
|
504
|
+
ADTProto[Symbol.for("showify.inspect.custom")] = inspect;
|
|
477
505
|
|
|
478
|
-
const ADTConstructorProto =
|
|
479
|
-
|
|
506
|
+
export const ADTConstructorProto = Object.create(PipeableFunctionProto);
|
|
507
|
+
ADTConstructorProto.toJSON = function toJSON() {
|
|
508
|
+
return { _tag: this.tag };
|
|
509
|
+
};
|
|
510
|
+
ADTConstructorProto[Symbol.for("nodejs.util.inspect.custom")] =
|
|
511
|
+
function inspect() {
|
|
512
|
+
return { _tag: this.tag };
|
|
513
|
+
};
|
|
514
|
+
ADTConstructorProto[Symbol.for("showify.inspect.custom")] = inspect;
|