diff --git a/src/lib/util/basic/utility.ts b/src/lib/util/basic/utility.ts
index abf01b8..4cdee12 100644
--- a/src/lib/util/basic/utility.ts
+++ b/src/lib/util/basic/utility.ts
@@ -1,11 +1,171 @@
import { type Either, left, right } from './either'
import { none, type Option, some } from './option'
-// Pipe function for composition
-export const pipe = (a: A, ab: (a: A) => B, bc: (b: B) => C): C =>
- bc(ab(a))
+interface Pipe {
+ (value: A): A
+ (value: A, fn1: (a: A) => B): B
+ (value: A, fn1: (a: A) => B, fn2: (b: B) => C): C
+ (
+ value: A,
+ fn1: (a: A) => B,
+ fn2: (b: B) => C,
+ fn3: (c: C) => D,
+ ): D
+ (
+ value: A,
+ fn1: (a: A) => B,
+ fn2: (b: B) => C,
+ fn3: (c: C) => D,
+ fn4: (d: D) => E,
+ ): E
+ (
+ value: A,
+ fn1: (a: A) => B,
+ fn2: (b: B) => C,
+ fn3: (c: C) => D,
+ fn4: (d: D) => E,
+ fn5: (e: E) => F,
+ ): F
+ (
+ value: A,
+ fn1: (a: A) => B,
+ fn2: (b: B) => C,
+ fn3: (c: C) => D,
+ fn4: (d: D) => E,
+ fn5: (e: E) => F,
+ fn6: (f: F) => G,
+ ): G
+ (
+ value: A,
+ fn1: (a: A) => B,
+ fn2: (b: B) => C,
+ fn3: (c: C) => D,
+ fn4: (d: D) => E,
+ fn5: (e: E) => F,
+ fn6: (f: F) => G,
+ fn7: (g: G) => H,
+ ): H
+ (
+ value: A,
+ fn1: (a: A) => B,
+ fn2: (b: B) => C,
+ fn3: (c: C) => D,
+ fn4: (d: D) => E,
+ fn5: (e: E) => F,
+ fn6: (f: F) => G,
+ fn7: (g: G) => H,
+ fn8: (h: H) => I,
+ ): I
+ (
+ value: A,
+ fn1: (a: A) => B,
+ fn2: (b: B) => C,
+ fn3: (c: C) => D,
+ fn4: (d: D) => E,
+ fn5: (e: E) => F,
+ fn6: (f: F) => G,
+ fn7: (g: G) => H,
+ fn8: (h: H) => I,
+ fn9: (i: I) => J,
+ ): J
+ (
+ value: A,
+ fn1: (a: A) => B,
+ fn2: (b: B) => C,
+ fn3: (c: C) => D,
+ fn4: (d: D) => E,
+ fn5: (e: E) => F,
+ fn6: (f: F) => G,
+ fn7: (g: G) => H,
+ fn8: (h: H) => I,
+ fn9: (i: I) => J,
+ fn10: (j: J) => K,
+ ): K
+}
+
+export const pipe: Pipe = (value: unknown, ...fns: Function[]): unknown => {
+ return fns.reduce((acc, fn) => fn(acc), value)
+}
+
+// Compose Function (reverse order)
+interface Compose {
+ (): (a: A) => A
+ (fn1: (a: A) => B): (a: A) => B
+ (fn2: (b: B) => C, fn1: (a: A) => B): (a: A) => C
+ (
+ fn3: (c: C) => D,
+ fn2: (b: B) => C,
+ fn1: (a: A) => B,
+ ): (a: A) => D
+ (
+ fn4: (d: D) => E,
+ fn3: (c: C) => D,
+ fn2: (b: B) => C,
+ fn1: (a: A) => B,
+ ): (a: A) => E
+ (
+ fn5: (e: E) => F,
+ fn4: (d: D) => E,
+ fn3: (c: C) => D,
+ fn2: (b: B) => C,
+ fn1: (a: A) => B,
+ ): (a: A) => F
+ (
+ fn6: (f: F) => G,
+ fn5: (e: E) => F,
+ fn4: (d: D) => E,
+ fn3: (c: C) => D,
+ fn2: (b: B) => C,
+ fn1: (a: A) => B,
+ ): (a: A) => G
+ (
+ fn7: (g: G) => H,
+ fn6: (f: F) => G,
+ fn5: (e: E) => F,
+ fn4: (d: D) => E,
+ fn3: (c: C) => D,
+ fn2: (b: B) => C,
+ fn1: (a: A) => B,
+ ): (a: A) => H
+ (
+ fn8: (h: H) => I,
+ fn7: (g: G) => H,
+ fn6: (f: F) => G,
+ fn5: (e: E) => F,
+ fn4: (d: D) => E,
+ fn3: (c: C) => D,
+ fn2: (b: B) => C,
+ fn1: (a: A) => B,
+ ): (a: A) => I
+ (
+ fn9: (i: I) => J,
+ fn8: (h: H) => I,
+ fn7: (g: G) => H,
+ fn6: (f: F) => G,
+ fn5: (e: E) => F,
+ fn4: (d: D) => E,
+ fn3: (c: C) => D,
+ fn2: (b: B) => C,
+ fn1: (a: A) => B,
+ ): (a: A) => J
+ (
+ fn10: (j: J) => K,
+ fn9: (i: I) => J,
+ fn8: (h: H) => I,
+ fn7: (g: G) => H,
+ fn6: (f: F) => G,
+ fn5: (e: E) => F,
+ fn4: (d: D) => E,
+ fn3: (c: C) => D,
+ fn2: (b: B) => C,
+ fn1: (a: A) => B,
+ ): (a: A) => K
+}
+
+export const compose: Compose = (...fns: Function[]) => {
+ return (value: unknown) => fns.reduceRight((acc, fn) => fn(acc), value)
+}
-// TryCatch helper using Either
export const tryCatch = (f: () => A): Either => {
try {
return right(f())
@@ -14,6 +174,5 @@ export const tryCatch = (f: () => A): Either => {
}
}
-// Option from nullable
export const fromNullable = (a: A | null | undefined): Option =>
a == null ? none : some(a)