From bf9c63812aef03f67ab26b5cc8e4bd4407b63f5f Mon Sep 17 00:00:00 2001 From: scarf Date: Sun, 17 Dec 2023 22:34:48 +0900 Subject: [PATCH 1/7] test: type check curried functions --- fp_test.ts | 16 +++++++++++++++- test_deps.ts | 4 ++++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/fp_test.ts b/fp_test.ts index b2efdfc..b180dc5 100644 --- a/fp_test.ts +++ b/fp_test.ts @@ -1,4 +1,10 @@ -import { assertArrayIncludes, assertEquals } from "./test_deps.ts"; +import { + assertArrayIncludes, + assertEquals, + assertType, + type IsExact, +} from "./test_deps.ts"; + import { c, p } from "https://deno.land/x/copb@v1.0.1/mod.ts"; import * as mod from "./mod.ts"; import * as fp from "./fp.ts"; @@ -7,6 +13,14 @@ Deno.test("All functions are available in functional programming version", () => assertArrayIncludes(["curried", ...Object.keys(fp)], Object.keys(mod)); }); +Deno.test("Curried functions with type predicates type checks", () => { + const xs = [1, "a", 2, "b"]; + const result = fp.find((x): x is number => typeof x === "number")(xs); + + assertType>(true); + assertEquals(result, 1); +}); + Deno.test("With copb", () => { const pipeline = c( p(fp.map((x) => x * 100)) // Only needed type annotation, the rest is inferred. diff --git a/test_deps.ts b/test_deps.ts index c3d25e5..b7dc03b 100644 --- a/test_deps.ts +++ b/test_deps.ts @@ -2,3 +2,7 @@ export { assert } from "https://deno.land/std@0.208.0/assert/assert.ts"; export { assertThrows } from "https://deno.land/std@0.208.0/assert/assert_throws.ts"; export { assertEquals } from "https://deno.land/std@0.208.0/assert/assert_equals.ts"; export { assertArrayIncludes } from "https://deno.land/std@0.208.0/assert/assert_array_includes.ts"; +export { + assertType, + type IsExact, +} from "https://deno.land/std@0.209.0/testing/types.ts"; From 65aab6dda4a0a66d1813b0a49f6ff7d7f07c7085 Mon Sep 17 00:00:00 2001 From: scarf Date: Sun, 17 Dec 2023 22:32:35 +0900 Subject: [PATCH 2/7] feat: `IterableTypePredicateCallback` --- lib/types.ts | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/lib/types.ts b/lib/types.ts index 3416239..4d35c19 100644 --- a/lib/types.ts +++ b/lib/types.ts @@ -28,6 +28,23 @@ export interface IterablePredicateCallback { (value: T, index: number, it: Iterable): boolean; } +/** + * Iterable type predicate callback. + * @typeParam T - Type of value to be predicated. + * @typeParam S - Type of value to be narrowed to. + */ +export interface IterableTypePredicateCallback { + /** + * Iterable type predicate callback. + * @callback IterableTypePredicateCallback + * @param value - The value of the item being predicated. + * @param index - The index of the item being predicated. + * @param it - The iterable. + * @returns The narrowed predicate result. + */ + (value: T, index: number, it: Iterable): value is S; +} + /** * The same as the `Iterable` type, but the iterator implementation is iterable. * @typeParam T - Type of items in the iterable. From f9ce8a7d01b29b5064e5d857a984557bb145cec9 Mon Sep 17 00:00:00 2001 From: scarf Date: Sun, 17 Dec 2023 22:33:06 +0900 Subject: [PATCH 3/7] feat: `every` --- lib/reducers.ts | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/lib/reducers.ts b/lib/reducers.ts index 94fa128..2446e82 100644 --- a/lib/reducers.ts +++ b/lib/reducers.ts @@ -1,5 +1,8 @@ import { kComb } from "./internal/util.ts"; -import { IterablePredicateCallback } from "./types.ts"; +import { + IterablePredicateCallback, + IterableTypePredicateCallback, +} from "./types.ts"; import { map } from "./transformers.ts"; /** @@ -160,6 +163,15 @@ export function some( * // const allPositive = iter.every(naturals, (n) => n > 0); * ``` */ + +export function every( + it: Iterable, + predicate: IterablePredicateCallback, +): boolean; +export function every( + it: Iterable, + predicate: IterableTypePredicateCallback, +): it is Iterable; export function every( it: Iterable, predicate: IterablePredicateCallback, From d24542677c581b90e80395bbd4f1a244aae2596c Mon Sep 17 00:00:00 2001 From: scarf Date: Sun, 17 Dec 2023 22:33:15 +0900 Subject: [PATCH 4/7] feat: `find` --- lib/reducers.ts | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/lib/reducers.ts b/lib/reducers.ts index 2446e82..bc75244 100644 --- a/lib/reducers.ts +++ b/lib/reducers.ts @@ -239,6 +239,14 @@ export function includes(it: Iterable, value: T): boolean { * // Find a solution to n³ = 3n, n ∈ ℕ * // const solution2 = iter.find(naturals, (n) => n ** 3 === 3 * n); */ +export function find( + it: Iterable, + predicate: IterablePredicateCallback, +): T | undefined; +export function find( + it: Iterable, + predicate: IterableTypePredicateCallback, +): S | undefined; export function find( it: Iterable, predicate: IterablePredicateCallback, From f955b7c77e81fed83679b48396a30a3ee766f609 Mon Sep 17 00:00:00 2001 From: scarf Date: Sun, 17 Dec 2023 22:33:30 +0900 Subject: [PATCH 5/7] feat: `takeWhile` --- lib/transformers.ts | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/lib/transformers.ts b/lib/transformers.ts index c48d09e..cffd0b0 100644 --- a/lib/transformers.ts +++ b/lib/transformers.ts @@ -2,6 +2,7 @@ import { isIterable } from "./internal/util.ts"; import { IterableCircular, IterablePredicateCallback, + IterableTypePredicateCallback, Peekable, } from "./types.ts"; @@ -318,6 +319,14 @@ export function dropUntil( * // -> 5 * ``` */ +export function takeWhile( + it: Iterable, + f: IterablePredicateCallback, +): IterableCircular; +export function takeWhile( + it: Iterable, + f: IterableTypePredicateCallback, +): IterableCircular; export function takeWhile( it: Iterable, f: IterablePredicateCallback, From bee4626b2d6a7da7c749f22516dffe9637051c45 Mon Sep 17 00:00:00 2001 From: scarf Date: Sun, 17 Dec 2023 22:33:37 +0900 Subject: [PATCH 6/7] feat: `filter` --- lib/transformers.ts | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/lib/transformers.ts b/lib/transformers.ts index cffd0b0..70fa2bc 100644 --- a/lib/transformers.ts +++ b/lib/transformers.ts @@ -395,6 +395,14 @@ export function dropWhile( * console.log(iterator.next().value); // -> 11 * ``` */ +export function filter( + it: Iterable, + predicate: IterablePredicateCallback, +): IterableCircular; +export function filter( + it: Iterable, + predicate: IterableTypePredicateCallback, +): IterableCircular; export function filter( it: Iterable, predicate: IterablePredicateCallback, From 6497713fb5856aa5a16e32f223c5e2682bcfcaeb Mon Sep 17 00:00:00 2001 From: scarf Date: Sun, 17 Dec 2023 22:38:31 +0900 Subject: [PATCH 7/7] feat: `dropWhile` --- lib/transformers.ts | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/lib/transformers.ts b/lib/transformers.ts index 70fa2bc..933c826 100644 --- a/lib/transformers.ts +++ b/lib/transformers.ts @@ -363,6 +363,14 @@ export function takeWhile( * // -> 10 * ``` */ +export function dropWhile( + it: Iterable, + f: IterablePredicateCallback, +): IterableCircular; +export function dropWhile( + it: Iterable, + f: IterableTypePredicateCallback, +): IterableCircular; export function dropWhile( it: Iterable, f: IterablePredicateCallback,