Repository: marpple/FxTS (ts)

Issue:
Add `apply` function
# Suggestion

<!--
  Please fill in each section completely. Thank you!
-->

## ⭐ Suggestion

<!-- What would you like to be added? -->

## 💻 Use Cases


```ts
apply(Math.max, [1, 2, 3, 4, 5]); // 5

pipe(
  repeat(10),
  map(a => a * Math.random())
  take(5),
  apply(max)
);
```


Pull request description:
feat: implement `apply` function
Fixes #83 


Patch:
diff --git a/src/apply.ts b/src/apply.ts
new file mode 100644
index 00000000..545d1bef
--- /dev/null
+++ b/src/apply.ts
@@ -0,0 +1,41 @@
+import Arrow from "./types/Arrow";
+
+/**
+ * Applies function `f` to the argument list `args`.
+ *
+ * @example
+ * ```ts
+ * apply(Math.max, [1, 2, 3, 4, 5]); // 5
+ *
+ * pipe(
+ *   repeat(10),
+ *   map(a => a * Math.random())
+ *   take(5),
+ *   apply(max)
+ * );
+ * ```
+ */
+
+function apply<F extends Arrow, T extends Parameters<F>>(
+  f: F,
+): (args: T) => ReturnType<typeof f>;
+
+function apply<F extends Arrow, T extends Parameters<F>>(
+  f: F,
+  args: T,
+): ReturnType<typeof f>;
+
+function apply<F extends Arrow, T extends Parameters<F>>(
+  f: F,
+  args?: T,
+):
+  | ReturnType<typeof f>
+  | ((args: Parameters<typeof f>) => ReturnType<typeof f>) {
+  if (args === undefined) {
+    return (args) => f(...args);
+  } else {
+    return f(...args);
+  }
+}
+
+export default apply;
diff --git a/src/index.ts b/src/index.ts
index 905db6e5..d093cdc1 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -1,3 +1,4 @@
+import apply from "./apply";
 import consume from "./consume";
 import countBy from "./countBy";
 import curry from "./curry";
@@ -34,6 +35,7 @@ import tap from "./tap";
 import toArray from "./toArray";
 
 export {
+  apply,
   consume,
   countBy,
   curry,


Test patch:
diff --git a/test/apply.spec.ts b/test/apply.spec.ts
new file mode 100644
index 00000000..e6a05f5b
--- /dev/null
+++ b/test/apply.spec.ts
@@ -0,0 +1,13 @@
+import { apply, range, pipe, toArray } from "../src/index";
+
+describe("apply", function () {
+  it("should apply given list to the function", function () {
+    const res = apply(Math.max, [1, 2, 3, 4, 5]);
+    expect(res).toEqual(5);
+  });
+
+  it("should be able to be used as a curried function in the pipeline", function () {
+    const res = pipe(range(1, 6), toArray, apply(Math.max));
+    expect(res).toEqual(5);
+  });
+});
diff --git a/type-check/apply.test.ts b/type-check/apply.test.ts
new file mode 100644
index 00000000..0e2a1f01
--- /dev/null
+++ b/type-check/apply.test.ts
@@ -0,0 +1,12 @@
+import * as Test from "../src/types/Test";
+import { apply, pipe, range, toArray } from "../src";
+
+const { checks, check } = Test;
+
+const res1 = apply(Math.max, [1, 2, 3, 4, 5]);
+const res2 = pipe(range(1, 6), toArray, apply(Math.max));
+
+checks([
+  check<typeof res1, ReturnType<typeof Math.max>, Test.Pass>(),
+  check<typeof res2, ReturnType<typeof Math.max>, Test.Pass>(),
+]);