diff --git a/src/Functional/Ary.php b/src/Functional/Ary.php index 404ad130..bef8f83d 100644 --- a/src/Functional/Ary.php +++ b/src/Functional/Ary.php @@ -11,11 +11,19 @@ namespace Functional; use Functional\Exceptions\InvalidArgumentException; -use Traversable; /** * Call $func with only abs($count) arguments, taken either from the * left or right depending on the sign + * + * @template V + * @template T + * + * @param callable(T...):V $func + * @param non-zero-int $count + * + * @return callable(T...):V + * * @no-named-arguments */ function ary(callable $func, int $count): callable diff --git a/src/Functional/Average.php b/src/Functional/Average.php index e9915707..0eb68454 100644 --- a/src/Functional/Average.php +++ b/src/Functional/Average.php @@ -11,13 +11,18 @@ namespace Functional; use Functional\Exceptions\InvalidArgumentException; -use Traversable; /** * Returns the average of all numeric values in the array or null if no numeric value was found * - * @param Traversable|array $collection - * @return null|float|int + * @param iterable $collection + * + * @return ($collection is iterable ? float|int : ( + * $collection is iterable ? float : ( + * $collection is iterable ? float|int : null + * ) + * )) + * * @no-named-arguments */ function average($collection) diff --git a/src/Functional/ButLast.php b/src/Functional/ButLast.php index 4f6d314c..c93484e5 100644 --- a/src/Functional/ButLast.php +++ b/src/Functional/ButLast.php @@ -11,13 +11,16 @@ namespace Functional; use Functional\Exceptions\InvalidArgumentException; -use Traversable; /** * Returns an array containing the elements of the list without its last element. * - * @param Traversable|array $collection - * @return array + * @template T + * + * @param iterable $collection + * + * @return iterable + * * @no-named-arguments */ function but_last($collection) diff --git a/src/Functional/Capture.php b/src/Functional/Capture.php index a3d9fc9f..217c53af 100644 --- a/src/Functional/Capture.php +++ b/src/Functional/Capture.php @@ -11,11 +11,15 @@ namespace Functional; /** - * Return a new function that captures the return value of $callback in $result and returns the callbacks return value + * Return a new function that captures the return value of $callback in $result and returns the callback's return value + * + * @template T + * + * @param callable():T $callback + * @param T $result + * + * @return callable():T * - * @param callable $callback - * @param mixed $result - * @return callable * @no-named-arguments */ function capture(callable $callback, &$result) diff --git a/src/Functional/CompareObjectHashOn.php b/src/Functional/CompareObjectHashOn.php index c4194479..cf8cf62a 100644 --- a/src/Functional/CompareObjectHashOn.php +++ b/src/Functional/CompareObjectHashOn.php @@ -13,9 +13,14 @@ /** * Returns a comparison function that can be used with e.g. `usort()` * - * @param callable $comparison A function that compares the two values. Pick e.g. strcmp() or strnatcasecmp() - * @param callable $keyFunction A function that takes an argument and returns the value that should be compared - * @return callable + * @template V + * @template R of int + * + * @param callable(string,string):R $comparison A function that compares the two values. Pick e.g. strcmp() or strnatcasecmp() + * @param null|callable(V):string $keyFunction A function that takes an argument and returns the value that should be compared + * + * @return callable(object,object):R + * * @no-named-arguments */ function compare_object_hash_on(callable $comparison, callable $keyFunction = null) diff --git a/src/Functional/CompareOn.php b/src/Functional/CompareOn.php index b0e5cda0..f16a4295 100644 --- a/src/Functional/CompareOn.php +++ b/src/Functional/CompareOn.php @@ -13,9 +13,15 @@ /** * Returns a comparison function that can be used with e.g. `usort()` * - * @param callable $comparison A function that compares the two values. Pick e.g. strcmp() or strnatcasecmp() - * @param callable $reducer A function that takes an argument and returns the value that should be compared - * @return callable + * @template V + * @template V2 + * @template R of int + * + * @param callable(V,V):R $comparison A function that compares the two values. Pick e.g. strcmp() or strnatcasecmp() + * @param null|callable(V2):V $reducer A function that takes an argument and returns the value that should be compared + * + * @return ($reducer is null ? callable(V,V):R : callable(V2,V2):R) + * * @no-named-arguments */ function compare_on(callable $comparison, callable $reducer = null) diff --git a/src/Functional/Concat.php b/src/Functional/Concat.php index 09426c6e..a54492a4 100644 --- a/src/Functional/Concat.php +++ b/src/Functional/Concat.php @@ -13,11 +13,13 @@ /** * Concatenates zero or more strings * - * @param string[] ...$strings + * @param string ...$strings + * * @return string + * * @no-named-arguments */ -function concat(string ...$strings) +function concat(...$strings) { return \implode('', $strings); } diff --git a/src/Functional/ConstFunction.php b/src/Functional/ConstFunction.php index 220cf009..1d1a20d6 100644 --- a/src/Functional/ConstFunction.php +++ b/src/Functional/ConstFunction.php @@ -13,8 +13,12 @@ /** * Wrap value within a function, which will return it, without any modifications. * - * @param mixed $value - * @return callable + * @template V + * + * @param V $value + * + * @return callable():V + * * @no-named-arguments */ function const_function($value) diff --git a/src/Functional/Contains.php b/src/Functional/Contains.php index b0fd5326..248e59f3 100644 --- a/src/Functional/Contains.php +++ b/src/Functional/Contains.php @@ -11,16 +11,20 @@ namespace Functional; use Functional\Exceptions\InvalidArgumentException; -use Traversable; /** * Returns true if the collection contains the given value. If the third parameter is * true values will be compared in strict mode * - * @param Traversable|array $collection - * @param mixed $value + * @template V + * @template V2 of V + * + * @param iterable $collection + * @param V2 $value * @param bool $strict + * * @return bool + * * @no-named-arguments */ function contains($collection, $value, $strict = true) diff --git a/src/Functional/Converge.php b/src/Functional/Converge.php index 4bbfc03c..271b659c 100644 --- a/src/Functional/Converge.php +++ b/src/Functional/Converge.php @@ -16,9 +16,15 @@ * The results of each branching function are passed as arguments * to the converging function to produce the return value. * - * @param callable $convergingFunction Will be invoked with the return values of all branching functions as its arguments - * @param callable[] $branchingFunctions A list of functions - * @return callable A flipped version of the given function + * @template V + * @template R + * @template R2 + * + * @param callable(R...):R2 $convergingFunction Will be invoked with the return values of all branching functions as its arguments + * @param array $branchingFunctions A list of functions + * + * @return callable(V...):R2 A flipped version of the given function + * * @no-named-arguments */ function converge($convergingFunction, array $branchingFunctions) diff --git a/src/Functional/Curry.php b/src/Functional/Curry.php index 52099360..7bd65c42 100644 --- a/src/Functional/Curry.php +++ b/src/Functional/Curry.php @@ -15,12 +15,17 @@ use Closure; /** - * Return a curryied version of the given function. You can decide if you also + * Return a curried version of the given function. You can decide if you also * want to curry optional parameters or not. * - * @param callable $function the function to curry - * @param bool $required curry optional parameters ? - * @return callable a curryied version of the given function + * @template V + * @template R + * + * @param callable(V...):R $function the function to curry + * @param bool $required curry optional parameters? + * + * @return callable(V...):R a curried version of the given function + * * @no-named-arguments */ function curry(callable $function, $required = true) diff --git a/src/Functional/CurryN.php b/src/Functional/CurryN.php index 780e34c9..fb851869 100644 --- a/src/Functional/CurryN.php +++ b/src/Functional/CurryN.php @@ -11,15 +11,20 @@ namespace Functional; /** - * Return a version of the given function where the $count first arguments are curryied. + * Return a version of the given function where the $count first arguments are curried. * * No check is made to verify that the given argument count is either too low or too high. * If you give a smaller number you will have an error when calling the given function. If * you give a higher number, arguments will simply be ignored. * + * @template R + * @template V + * * @param int $count number of arguments you want to curry - * @param callable $function the function you want to curry - * @return callable a curryied version of the given function + * @param callable(V...):R $function the function you want to curry + * + * @return callable(V...):R a curried version of the given function + * * @no-named-arguments */ function curry_n($count, callable $function) diff --git a/src/Functional/Difference.php b/src/Functional/Difference.php index 8984eb12..d8984738 100644 --- a/src/Functional/Difference.php +++ b/src/Functional/Difference.php @@ -11,14 +11,18 @@ namespace Functional; use Functional\Exceptions\InvalidArgumentException; -use Traversable; /** * Takes a collection and returns the difference of all elements * - * @param Traversable|array $collection - * @param integer|float $initial - * @return integer|float + * @template V + * @template I of int|float + * + * @param iterable $collection + * @param I $initial + * + * @return (V is int ? ($initial is int ? int : float) : (V is float ? float : int|float)) + * * @no-named-arguments */ function difference($collection, $initial = 0) diff --git a/src/Functional/DropFirst.php b/src/Functional/DropFirst.php index 71249c02..af8f9fb1 100644 --- a/src/Functional/DropFirst.php +++ b/src/Functional/DropFirst.php @@ -11,14 +11,18 @@ namespace Functional; use Functional\Exceptions\InvalidArgumentException; -use Traversable; /** * Drop all elements from a collection until callback returns false * - * @param Traversable|array $collection - * @param callable $callback - * @return array + * @template K of array-key + * @template V + * + * @param iterable $collection + * @param callable(V, K, iterable):bool $callback + * + * @return (K is numeric-string ? array : array) + * * @no-named-arguments */ function drop_first($collection, callable $callback) diff --git a/src/Functional/DropLast.php b/src/Functional/DropLast.php index 666c4e76..82cb286c 100644 --- a/src/Functional/DropLast.php +++ b/src/Functional/DropLast.php @@ -11,14 +11,18 @@ namespace Functional; use Functional\Exceptions\InvalidArgumentException; -use Traversable; /** * Drop all elements from a collection after callback returns true * - * @param Traversable|array $collection - * @param callable $callback - * @return array + * @template K of array-key + * @template V + * + * @param iterable $collection + * @param callable(V, K, iterable):bool $callback + * + * @return (K is numeric-string ? array : array) + * * @no-named-arguments */ function drop_last($collection, callable $callback) diff --git a/src/Functional/Each.php b/src/Functional/Each.php index 3720a725..4686574e 100644 --- a/src/Functional/Each.php +++ b/src/Functional/Each.php @@ -11,15 +11,19 @@ namespace Functional; use Functional\Exceptions\InvalidArgumentException; -use Traversable; /** * Iterates over a collection of elements, yielding each in turn to a callback function. Each invocation of $callback * is called with three arguments: (element, index, collection) * - * @param Traversable|array $collection - * @param callable $callback - * @return null + * @template K + * @template V + * + * @param iterable $collection + * @param callable(V,K,iterable):void $callback + * + * @return void + * * @no-named-arguments */ function each($collection, callable $callback) diff --git a/src/Functional/Entries.php b/src/Functional/Entries.php index 1fc22531..fc47234d 100644 --- a/src/Functional/Entries.php +++ b/src/Functional/Entries.php @@ -11,16 +11,21 @@ namespace Functional; use Functional\Exceptions\InvalidArgumentException; -use Traversable; /** * Inspired by JavaScript’s `Object.entries`, and Python’s `enumerate`, * convert a key-value map into an array of key-value pairs * - * @see Functional\from_entries - * @param Traversable|array $collection + * @see \Functional\from_entries + * + * @template K + * @template V + * + * @param iterable $collection * @param int $start - * @return array + * + * @return array + * * @no-named-arguments */ function entries($collection, int $start = 0) diff --git a/src/Functional/Equal.php b/src/Functional/Equal.php index 4a7c2b11..03d56b46 100644 --- a/src/Functional/Equal.php +++ b/src/Functional/Equal.php @@ -15,7 +15,8 @@ * * @param mixed $b the value to compare to * - * @return callable the function to perform the comparison + * @return callable(mixed):bool the function to perform the comparison + * * @no-named-arguments */ function equal($b) diff --git a/src/Functional/ErrorToException.php b/src/Functional/ErrorToException.php index 5051bc45..60f14035 100644 --- a/src/Functional/ErrorToException.php +++ b/src/Functional/ErrorToException.php @@ -15,10 +15,16 @@ /** * Takes a function and returns a new function that wraps the callback and rethrows PHP errors as exception * - * @param callable $callback - * @throws ErrorException Throws exception if PHP error happened - * @return mixed + * @template V + * @template R + * + * @param callable(V...):R $callback + * + * @return callable(V...):R + * * @no-named-arguments + *@throws ErrorException Throws exception if PHP error happened + * */ function error_to_exception(callable $callback) { diff --git a/src/Functional/Every.php b/src/Functional/Every.php index e4d8ff62..af5d44aa 100644 --- a/src/Functional/Every.php +++ b/src/Functional/Every.php @@ -11,27 +11,27 @@ namespace Functional; use Functional\Exceptions\InvalidArgumentException; -use Traversable; /** * Returns true if every value in the collection passes the callback truthy test. Opposite of Functional\none(). * Callback arguments will be element, index, collection * - * @param Traversable|array $collection - * @param callable|null $callback + * @template K + * @template V + * + * @param iterable $collection + * @param null|callable(V,K,iterable):bool $callback + * * @return bool + * * @no-named-arguments */ function every($collection, callable $callback = null) { InvalidArgumentException::assertCollection($collection, __FUNCTION__, 1); - if ($callback === null) { - $callback = '\Functional\id'; - } - foreach ($collection as $index => $element) { - if (!$callback($element, $index, $collection)) { + if (!(null === $callback ? id($element) : $callback($element, $index, $collection))) { return false; } } diff --git a/src/Functional/False.php b/src/Functional/False.php index ff41c035..e0d38327 100644 --- a/src/Functional/False.php +++ b/src/Functional/False.php @@ -11,13 +11,14 @@ namespace Functional; use Functional\Exceptions\InvalidArgumentException; -use Traversable; /** - * Returns true if all elements of the collection are strictly false + * Returns true if all elements of the collection are strictly false or the collection is empty + * + * @param iterable $collection * - * @param Traversable|array $collection * @return bool + * * @no-named-arguments */ function false($collection) diff --git a/src/Functional/Falsy.php b/src/Functional/Falsy.php index e16be719..44d3edb6 100644 --- a/src/Functional/Falsy.php +++ b/src/Functional/Falsy.php @@ -11,13 +11,14 @@ namespace Functional; use Functional\Exceptions\InvalidArgumentException; -use Traversable; /** - * Returns true if all elements of the collection evaluate to false + * Returns true if all elements of the collection evaluate to false or the collection is empty + * + * @param iterable $collection * - * @param Traversable|array $collection * @return bool + * * @no-named-arguments */ function falsy($collection) diff --git a/src/Functional/Filter.php b/src/Functional/Filter.php index 46e09781..9f93e9ac 100644 --- a/src/Functional/Filter.php +++ b/src/Functional/Filter.php @@ -11,14 +11,18 @@ namespace Functional; use Functional\Exceptions\InvalidArgumentException; -use Traversable; /** * Alias of Functional\select() * - * @param Traversable|array $collection - * @param callable $callback - * @return array + * @template K of array-key + * @template V + * + * @param iterable $collection + * @param callable(V,K,iterable):mixed $callback + * + * @return (K is numeric-string ? array : array) + * * @no-named-arguments */ function filter($collection, callable $callback) diff --git a/src/Functional/First.php b/src/Functional/First.php index 87db945e..48331a92 100644 --- a/src/Functional/First.php +++ b/src/Functional/First.php @@ -11,16 +11,20 @@ namespace Functional; use Functional\Exceptions\InvalidArgumentException; -use Traversable; /** * Looks through each element in the collection, returning the first one that passes a truthy test (callback). The * function returns as soon as it finds an acceptable element, and doesn't traverse the entire collection. Callback * arguments will be element, index, collection * - * @param Traversable|array $collection - * @param callable $callback - * @return mixed + * @template T + * @template I + * + * @param iterable $collection + * @param null|callable(T,I,iterable):bool $callback + * + * @return ($collection is non-empty-array ? ($callback is null ? T : T|null) : T|null) + * * @no-named-arguments */ function first($collection, callable $callback = null) diff --git a/src/Functional/FirstIndexOf.php b/src/Functional/FirstIndexOf.php index 0fb5a0ad..f511d4dd 100644 --- a/src/Functional/FirstIndexOf.php +++ b/src/Functional/FirstIndexOf.php @@ -11,14 +11,18 @@ namespace Functional; use Functional\Exceptions\InvalidArgumentException; -use Traversable; /** * Returns the first index holding specified value in the collection. Returns false if value was not found * - * @param Traversable|array $collection - * @param mixed $value - * @return mixed + * @template K + * @template V + * + * @param iterable $collection + * @param V $value + * + * @return false|K + * * @no-named-arguments */ function first_index_of($collection, $value) diff --git a/src/Functional/FlatMap.php b/src/Functional/FlatMap.php index 6a022f49..dcfcf026 100644 --- a/src/Functional/FlatMap.php +++ b/src/Functional/FlatMap.php @@ -24,9 +24,15 @@ * then flat_map(collection, callback) will return [1,2,3,[4]] * while flatten(map(collection, callback)) will return [1,2,3,4] * - * @param Traversable|array $collection - * @param callable $callback - * @return array + * @template K of array-key + * @template V + * @template V2 + * + * @param iterable $collection + * @param callable(V,K,iterable):(V2|iterable) $callback + * + * @return list + * * @no-named-arguments */ function flat_map($collection, callable $callback) diff --git a/src/Functional/Flatten.php b/src/Functional/Flatten.php index 615bfb5e..77818c56 100644 --- a/src/Functional/Flatten.php +++ b/src/Functional/Flatten.php @@ -17,8 +17,10 @@ * Takes a nested combination of collections and returns their contents as a single, flat array. * Does not preserve indexes. * - * @param Traversable|array $collection - * @return array + * @param iterable $collection + * + * @return array + * * @no-named-arguments */ function flatten($collection) diff --git a/src/Functional/Flip.php b/src/Functional/Flip.php index 9beedc8a..33ebc6b7 100644 --- a/src/Functional/Flip.php +++ b/src/Functional/Flip.php @@ -15,8 +15,13 @@ * * If one argument is provided, it is passed to the function without change. * - * @param callable $callback the function you want to flip - * @return callable a flipped version of the given function + * @template V + * @template R + * + * @param callable(V...):R $callback the function you want to flip + * + * @return callable(V...):R a flipped version of the given function + * * @no-named-arguments */ function flip(callable $callback) diff --git a/src/Functional/FromEntries.php b/src/Functional/FromEntries.php index 65dd5ffc..0e12194c 100644 --- a/src/Functional/FromEntries.php +++ b/src/Functional/FromEntries.php @@ -11,15 +11,21 @@ namespace Functional; use Functional\Exceptions\InvalidArgumentException; -use Traversable; /** * Inspired by JavaScript’s `Object.fromEntries`, * convert an array of key-value pairs into a key-value map * - * @see Functional\entries - * @param Traversable|array $collection - * @return array + * @see \Functional\entries + * + * @template K of array-key + * @template V + * @template P of array{K,V} + * + * @param iterable

$collection + * + * @return (K is numeric-string ? array : array) + * * @no-named-arguments */ function from_entries($collection) @@ -30,7 +36,7 @@ function from_entries($collection) foreach ($collection as $entry) { InvalidArgumentException::assertPair($entry, __FUNCTION__, 1); [$key, $value] = $entry; - InvalidArgumentException::assertValidArrayKey($key, __FUNCTION__, 1); + InvalidArgumentException::assertValidArrayKey($key, __FUNCTION__); $aggregation[$key] = $value; } diff --git a/src/Functional/GreaterThan.php b/src/Functional/GreaterThan.php index f3c84583..8014feb5 100644 --- a/src/Functional/GreaterThan.php +++ b/src/Functional/GreaterThan.php @@ -14,7 +14,9 @@ * Returns true if $a is strictly greater than $b. * * @param mixed $b - * @return \Closure(mixed) + * + * @return callable(mixed): bool + * * @no-named-arguments */ function greater_than($b) diff --git a/src/Functional/GreaterThanOrEqual.php b/src/Functional/GreaterThanOrEqual.php index 266fd50f..e51a89ca 100644 --- a/src/Functional/GreaterThanOrEqual.php +++ b/src/Functional/GreaterThanOrEqual.php @@ -14,7 +14,9 @@ * Returns true if $a is greater than or equal to $b. * * @param mixed $b - * @return \Closure(mixed) + * + * @return callable(mixed): bool + * * @no-named-arguments */ function greater_than_or_equal($b) diff --git a/src/Functional/Group.php b/src/Functional/Group.php index af2ed3a1..00ea5ef7 100644 --- a/src/Functional/Group.php +++ b/src/Functional/Group.php @@ -11,14 +11,25 @@ namespace Functional; use Functional\Exceptions\InvalidArgumentException; -use Traversable; /** * Groups a collection by index returned by callback. * - * @param Traversable|array $collection - * @param callable $callback - * @return array + * @template K of array-key + * @template V + * @template G of array-key + * + * @param iterable $collection + * @param callable(V,K,iterable):G $callback + * + * @return (G is numeric-string + * ? (K is numeric-string + * ? array> + * : array> + * ) + * : array> + * ) + * * @no-named-arguments */ function group($collection, callable $callback) diff --git a/src/Functional/Head.php b/src/Functional/Head.php index c6de5e86..5dde05d7 100644 --- a/src/Functional/Head.php +++ b/src/Functional/Head.php @@ -11,14 +11,18 @@ namespace Functional; use Functional\Exceptions\InvalidArgumentException; -use Traversable; /** * Alias for Functional\first * - * @param Traversable|array $collection - * @param callable $callback - * @return mixed + * @template T + * @template I + * + * @param iterable $collection + * @param null|callable(T,I,iterable):bool $callback + * + * @return ($collection is non-empty-array ? ($callback is null ? T : T|null) : T|null) + * * @no-named-arguments */ function head($collection, callable $callback = null) diff --git a/src/Functional/Id.php b/src/Functional/Id.php index b7de88dc..a1153b2f 100644 --- a/src/Functional/Id.php +++ b/src/Functional/Id.php @@ -13,8 +13,12 @@ /** * Return value itself, without any modifications. * - * @param mixed $value - * @return mixed + * @template T + * + * @param T $value + * + * @return T + * * @no-named-arguments */ function id($value) diff --git a/src/Functional/Identical.php b/src/Functional/Identical.php index 07f31501..39853db8 100644 --- a/src/Functional/Identical.php +++ b/src/Functional/Identical.php @@ -14,7 +14,9 @@ * Returns true if $a is equal to $b, and they are of the same type. * * @param mixed $b - * @return callable + * + * @return callable(mixed):bool + * * @no-named-arguments */ function identical($b) diff --git a/src/Functional/IfElse.php b/src/Functional/IfElse.php index 607bd635..c2540b3d 100644 --- a/src/Functional/IfElse.php +++ b/src/Functional/IfElse.php @@ -13,11 +13,16 @@ /** * Performs an if/else condition over a value using functions as statements * - * @param callable $if the condition function - * @param callable $then function to call if condition is true - * @param callable $else function to call if condition is false + * @template V + * @template R1 + * @template R2 + * + * @param callable(V):mixed $if the condition function + * @param callable(V):R1 $then function to call if condition is true + * @param callable(V):R2 $else function to call if condition is false + * + * @return callable(V):(R1|R2) a callback that returns the value of the given $then or $else functions * - * @return mixed the return value of the given $then or $else functions * @no-named-arguments */ function if_else(callable $if, callable $then, callable $else) diff --git a/src/Functional/IndexesOf.php b/src/Functional/IndexesOf.php index 74f05b77..375b63c8 100644 --- a/src/Functional/IndexesOf.php +++ b/src/Functional/IndexesOf.php @@ -11,15 +11,19 @@ namespace Functional; use Functional\Exceptions\InvalidArgumentException; -use Traversable; /** - * Returns a list of array indexes, either matching the predicate or strictly equal to the the passed value. Returns an - * empty array if no values were found. + * Returns a list of array indexes, either matching the predicate or strictly equal to the passed value. + * Returns an empty array if no values were found. + * + * @template K of array-key + * @template V + * + * @param iterable $collection + * @param V $value + * + * @return list * - * @param Traversable|array $collection - * @param mixed $value - * @return array * @no-named-arguments */ function indexes_of($collection, $value) diff --git a/src/Functional/Intersperse.php b/src/Functional/Intersperse.php index 4b325ad2..e082d04b 100644 --- a/src/Functional/Intersperse.php +++ b/src/Functional/Intersperse.php @@ -11,15 +11,19 @@ namespace Functional; use Functional\Exceptions\InvalidArgumentException; -use Traversable; /** * Insert a given value between each element of a collection. * Indices are not preserved. * - * @param Traversable|array $collection - * @param mixed $glue - * @return array + * @template V + * @template G + * + * @param iterable $collection + * @param G $glue + * + * @return list + * * @no-named-arguments */ function intersperse($collection, $glue) diff --git a/src/Functional/Invoke.php b/src/Functional/Invoke.php index 5970ed33..b7c60c11 100644 --- a/src/Functional/Invoke.php +++ b/src/Functional/Invoke.php @@ -11,16 +11,19 @@ namespace Functional; use Functional\Exceptions\InvalidArgumentException; -use Traversable; /** - * Calls the method named by $methodName on each value in the collection. Any extra arguments passed to invoke will be - * forwarded on to the method invocation. + * Calls the method named by $methodName on each value in the collection. + * Any extra arguments passed to invoke will be forwarded on to the method invocation. * - * @param Traversable|array $collection + * @template K of array-key + * + * @param iterable $collection * @param string $methodName - * @param array $arguments - * @return array + * @param array $arguments + * + * @return (K is numeric-string ? array : array) + * * @no-named-arguments */ function invoke($collection, $methodName, array $arguments = []) diff --git a/src/Functional/InvokeFirst.php b/src/Functional/InvokeFirst.php index 8fc8b935..5dc7368f 100644 --- a/src/Functional/InvokeFirst.php +++ b/src/Functional/InvokeFirst.php @@ -11,17 +11,17 @@ namespace Functional; use Functional\Exceptions\InvalidArgumentException; -use Traversable; /** * Calls the method named by $methodName on first object in the collection containing a callable method named * $methodName. Any extra arguments passed to invoke will be forwarded on to the method invocation. * - * @param Traversable|array $collection + * @param iterable $collection * @param string $methodName - * @param array $arguments + * @param array $arguments * * @return mixed + * * @no-named-arguments */ function invoke_first($collection, $methodName, array $arguments = []) diff --git a/src/Functional/InvokeIf.php b/src/Functional/InvokeIf.php index 7f0a4b36..eebb1e9f 100644 --- a/src/Functional/InvokeIf.php +++ b/src/Functional/InvokeIf.php @@ -14,11 +14,13 @@ * Calls the method named by $methodName on $object. Any extra arguments passed to invoke_if will be * forwarded on to the method invocation. If $method is not callable on $object, $defaultValue is returned. * - * @param mixed $object + * @param object $object * @param string $methodName - * @param array $methodArguments + * @param array $methodArguments * @param mixed $defaultValue + * * @return mixed + * * @no-named-arguments */ function invoke_if($object, $methodName, array $methodArguments = [], $defaultValue = null) diff --git a/src/Functional/InvokeLast.php b/src/Functional/InvokeLast.php index b63cfbfa..d2d51470 100644 --- a/src/Functional/InvokeLast.php +++ b/src/Functional/InvokeLast.php @@ -10,17 +10,18 @@ namespace Functional; -use Traversable; use Functional\Exceptions\InvalidArgumentException; /** * Calls the method named by $methodName on last object in the collection containing a callable method named * $methodName. Any extra arguments passed to invoke will be forwarded on to the method invocation. * - * @param Traversable|array $collection + * @param iterable $collection * @param string $methodName - * @param array $arguments + * @param array $arguments + * * @return mixed + * * @no-named-arguments */ function invoke_last($collection, $methodName, array $arguments = []) diff --git a/src/Functional/Invoker.php b/src/Functional/Invoker.php index 5236cf49..bcc97dc4 100644 --- a/src/Functional/Invoker.php +++ b/src/Functional/Invoker.php @@ -10,15 +10,16 @@ namespace Functional; -use Traversable; use Functional\Exceptions\InvalidArgumentException; /** * Returns a function that invokes method `$method` with arguments `$methodArguments` on the object * * @param string $methodName - * @param array $arguments - * @return callable + * @param array $arguments + * + * @return callable(object):mixed + * * @no-named-arguments */ function invoker($methodName, array $arguments = []) diff --git a/src/Functional/Last.php b/src/Functional/Last.php index 8989f945..4e4db77b 100644 --- a/src/Functional/Last.php +++ b/src/Functional/Last.php @@ -11,15 +11,23 @@ namespace Functional; use Functional\Exceptions\InvalidArgumentException; -use Traversable; /** * Looks through each element in the collection, returning the last one that passes a truthy test (callback). * Callback arguments will be element, index, collection * - * @param Traversable|array $collection - * @param callable $callback - * @return mixed + * @template K of array-key + * @template V + * + * @param iterable $collection + * @param null|callable(V,K,iterable):bool $callback + * + * @return ( + * $collection is non-empty-array + * ? ($callback is null ? V : null|V) + * : null|V + * ) + * * @no-named-arguments */ function last($collection, callable $callback = null) diff --git a/src/Functional/LastIndexOf.php b/src/Functional/LastIndexOf.php index fc540193..0bf01994 100644 --- a/src/Functional/LastIndexOf.php +++ b/src/Functional/LastIndexOf.php @@ -11,14 +11,18 @@ namespace Functional; use Functional\Exceptions\InvalidArgumentException; -use Traversable; /** * Returns the last index holding specified value in the collection. Returns false if value was not found * - * @param Traversable|array $collection - * @param mixed $value - * @return mixed + * @template K + * @template V + * + * @param iterable $collection + * @param V $value + * + * @return false|K + * * @no-named-arguments */ function last_index_of($collection, $value) diff --git a/src/Functional/LessThan.php b/src/Functional/LessThan.php index 062dc865..516562d3 100644 --- a/src/Functional/LessThan.php +++ b/src/Functional/LessThan.php @@ -14,7 +14,9 @@ * Returns true if $a is strictly less than $b. * * @param mixed $b - * @return \Closure(mixed) + * + * @return callable(mixed):bool + * * @no-named-arguments */ function less_than($b) diff --git a/src/Functional/LessThanOrEqual.php b/src/Functional/LessThanOrEqual.php index d63cb50b..608f1bd2 100644 --- a/src/Functional/LessThanOrEqual.php +++ b/src/Functional/LessThanOrEqual.php @@ -14,7 +14,9 @@ * Returns true if $a is less than or equal to $b. * * @param mixed $b - * @return \Closure(mixed) + * + * @return callable(mixed):bool + * * @no-named-arguments */ function less_than_or_equal($b) diff --git a/src/Functional/LexicographicCompare.php b/src/Functional/LexicographicCompare.php index c025daea..152d92c2 100644 --- a/src/Functional/LexicographicCompare.php +++ b/src/Functional/LexicographicCompare.php @@ -15,7 +15,9 @@ * $a is respectively less than, equal to, or greater than $b. * * @param mixed $b - * @return \Closure(mixed) + * + * @return callable(mixed):int + * * @no-named-arguments */ function lexicographic_compare($b) diff --git a/src/Functional/Map.php b/src/Functional/Map.php index 1bd577b3..f4a712a4 100644 --- a/src/Functional/Map.php +++ b/src/Functional/Map.php @@ -11,15 +11,20 @@ namespace Functional; use Functional\Exceptions\InvalidArgumentException; -use Traversable; /** * Produces a new array of elements by mapping each element in collection through a transformation function (callback). * Callback arguments will be element, index, collection * - * @param Traversable|array $collection - * @param callable $callback - * @return array + * @template K of array-key + * @template V + * @template V2 + * + * @param iterable $collection + * @param callable(V,K,iterable):V2 $callback + * + * @return (K is numeric-string ? array : array) + * * @no-named-arguments */ function map($collection, callable $callback) diff --git a/src/Functional/Matching.php b/src/Functional/Matching.php index d941f86a..2bcfd98c 100644 --- a/src/Functional/Matching.php +++ b/src/Functional/Matching.php @@ -21,9 +21,20 @@ /** * Performs an operation checking for the given conditions * - * @param array $conditions the conditions to check against + * @template V + * @template R + * + * @param array $conditions the conditions to check against + * + * @return ( + * $conditions is non-empty-array + * ? callable(V):(null|R) + * : callable(V):null + * ) the function that calls the callable of the first truthy condition * - * @return callable|null the function that calls the callable of the first truthy condition * @no-named-arguments */ function matching(array $conditions) diff --git a/src/Functional/Maximum.php b/src/Functional/Maximum.php index 8d8d5fb2..204fb70f 100644 --- a/src/Functional/Maximum.php +++ b/src/Functional/Maximum.php @@ -11,13 +11,16 @@ namespace Functional; use Functional\Exceptions\InvalidArgumentException; -use Traversable; /** * Returns the maximum value of a collection * - * @param Traversable|array $collection - * @return integer|float + * @template V + * + * @param iterable $collection + * + * @return null|V + * * @no-named-arguments */ function maximum($collection) diff --git a/src/Functional/Memoize.php b/src/Functional/Memoize.php index 3813e3ce..2d28c5a2 100644 --- a/src/Functional/Memoize.php +++ b/src/Functional/Memoize.php @@ -15,10 +15,15 @@ /** * Memoizes callbacks and returns their value instead of calling them * - * @param callable|null $callback Callable closure or function. Pass null to reset memory - * @param array $arguments Arguments - * @param array|string $key Optional memoize key to override the auto calculated hash - * @return mixed + * @template V + * @template R + * + * @param null|callable(V):R $callback Callable closure or function. Pass null to reset memory + * @param array $arguments Arguments + * @param mixed $key Optional memoize key to override the auto calculated hash + * + * @return ($callback is null ? null : R) + * * @no-named-arguments */ function memoize(callable $callback = null, $arguments = [], $key = null) @@ -34,7 +39,7 @@ function memoize(callable $callback = null, $arguments = [], $key = null) \trigger_error('Passing a callable as key is deprecated and will be removed in 2.0', E_USER_DEPRECATED); $key = $key(); } elseif (\is_callable($arguments)) { - \trigger_error('Passing a callable as key is deprecated and will be removed in 2.0', E_USER_DEPRECATED); + \trigger_error('Passing a callable as arguments is deprecated and will be removed in 2.0', E_USER_DEPRECATED); $key = $arguments(); } diff --git a/src/Functional/Minimum.php b/src/Functional/Minimum.php index 053b0beb..950d2cd1 100644 --- a/src/Functional/Minimum.php +++ b/src/Functional/Minimum.php @@ -11,13 +11,16 @@ namespace Functional; use Functional\Exceptions\InvalidArgumentException; -use Traversable; /** * Returns the minimum value of a collection * - * @param Traversable|array $collection - * @return integer|float + * @template V + * + * @param iterable $collection + * + * @return null|V + * * @no-named-arguments */ function minimum($collection) @@ -26,7 +29,7 @@ function minimum($collection) $min = null; - foreach ($collection as $index => $element) { + foreach ($collection as $element) { if (!\is_numeric($element)) { continue; } diff --git a/src/Functional/None.php b/src/Functional/None.php index edbd33a9..9b42e163 100644 --- a/src/Functional/None.php +++ b/src/Functional/None.php @@ -11,27 +11,28 @@ namespace Functional; use Functional\Exceptions\InvalidArgumentException; -use Traversable; /** - * Returns true if all of the elements in the collection pass the callback falsy test. Opposite of Functional\all(). + * Returns true if all of the elements in the collection pass the callback falsy test. + * Opposite of Functional\all(). * Callback arguments will be element, index, collection. * - * @param Traversable|array $collection - * @param callable|null $callback + * @template K of array-key + * @template V + * + * @param iterable $collection + * @param null|callable(V,K,iterable):mixed $callback + * * @return bool + * * @no-named-arguments */ function none($collection, callable $callback = null) { InvalidArgumentException::assertCollection($collection, __FUNCTION__, 1); - if ($callback === null) { - $callback = '\Functional\id'; - } - foreach ($collection as $index => $element) { - if ($callback($element, $index, $collection)) { + if (null === $callback ? id($element) : $callback($element, $index, $collection)) { return false; } } diff --git a/src/Functional/Noop.php b/src/Functional/Noop.php index 69f9ee2b..bc5594ca 100644 --- a/src/Functional/Noop.php +++ b/src/Functional/Noop.php @@ -26,6 +26,9 @@ /** * A no-operation function. + * + * @return void + * * @no-named-arguments */ function noop() diff --git a/src/Functional/Not.php b/src/Functional/Not.php index 9599bea8..fdb13dea 100644 --- a/src/Functional/Not.php +++ b/src/Functional/Not.php @@ -13,8 +13,12 @@ /** * Logical negation of the given $function * - * @param callable $function The function to run value against - * @return callable A negation version on the given $function + * @template V + * + * @param callable(V):mixed $function The function to run value against + * + * @return callable(V):bool A negation version on the given $function + * * @no-named-arguments */ function not(callable $function) diff --git a/src/Functional/OmitKeys.php b/src/Functional/OmitKeys.php index c08a69b4..1076a146 100644 --- a/src/Functional/OmitKeys.php +++ b/src/Functional/OmitKeys.php @@ -16,9 +16,13 @@ /** * Returns an array with the specified keys omitted from the array * - * @param Traversable|array $collection - * @param array $keys - * @return array + * @template V + * + * @param iterable $collection + * @param array $keys + * + * @return array + * * @no-named-arguments */ function omit_keys($collection, array $keys) diff --git a/src/Functional/PartialAny.php b/src/Functional/PartialAny.php index 71a481dc..0f852161 100644 --- a/src/Functional/PartialAny.php +++ b/src/Functional/PartialAny.php @@ -17,9 +17,14 @@ * * Use Functional\…, Functional\…() or Functional\placeholder() as a placeholder * - * @param callable $callback - * @param mixed ...$arguments - * @return callable + * @template V + * @template R + * + * @param callable(V...):R $callback + * @param V ...$arguments + * + * @return callable(V...):R + * * @no-named-arguments */ function partial_any(callable $callback, ...$arguments) @@ -40,6 +45,7 @@ function partial_any(callable $callback, ...$arguments) /** * @return resource + * * @no-named-arguments */ function …() @@ -56,6 +62,7 @@ function …() /** * @return resource + * * @no-named-arguments */ function placeholder() diff --git a/src/Functional/PartialLeft.php b/src/Functional/PartialLeft.php index e4ae016c..b66e921e 100644 --- a/src/Functional/PartialLeft.php +++ b/src/Functional/PartialLeft.php @@ -15,9 +15,14 @@ * * Use Functional\…, Functional\…() or Functional\placeholder() as a placeholder * - * @param callable $callback - * @param array ...$arguments - * @return callable + * @template V + * @template R + * + * @param callable(V...):R $callback + * @param V ...$arguments + * + * @return callable(V...):R + * * @no-named-arguments */ function partial_left(callable $callback, ...$arguments) diff --git a/src/Functional/PartialMethod.php b/src/Functional/PartialMethod.php index ac1f7239..f17c50bb 100644 --- a/src/Functional/PartialMethod.php +++ b/src/Functional/PartialMethod.php @@ -15,10 +15,14 @@ /** * Returns a function that expects an object as the first param and tries to invoke the given method on it * + * @template V + * * @param string $methodName - * @param array $arguments + * @param array $arguments * @param mixed $defaultValue - * @return callable + * + * @return callable(object):mixed + * * @no-named-arguments */ function partial_method($methodName, array $arguments = [], $defaultValue = null) diff --git a/src/Functional/PartialRight.php b/src/Functional/PartialRight.php index 601e990b..a2e9fa6f 100644 --- a/src/Functional/PartialRight.php +++ b/src/Functional/PartialRight.php @@ -13,9 +13,14 @@ /** * Return a new function with the arguments partially applied starting from the right * - * @param callable $callback - * @param array ...$arguments - * @return callable + * @template V + * @template R + * + * @param callable(V...):R $callback + * @param V ...$arguments + * + * @return callable(V...):R + * * @no-named-arguments */ function partial_right(callable $callback, ...$arguments) diff --git a/src/Functional/Partition.php b/src/Functional/Partition.php index 11fb36b9..7509d723 100644 --- a/src/Functional/Partition.php +++ b/src/Functional/Partition.php @@ -11,7 +11,6 @@ namespace Functional; use Functional\Exceptions\InvalidArgumentException; -use Traversable; /** * Partitions a collection by callback predicate results. Returns an @@ -22,9 +21,14 @@ * Elements are not re-ordered and have the same index they had in the * original array. * - * @param Traversable|array $collection - * @param callable ...$callbacks - * @return array + * @template K of array-key + * @template V + * + * @param iterable $collection + * @param callable(V,K,iterable):mixed ...$callbacks + * + * @return (K is numeric-string ? list> : list>) + * * @no-named-arguments */ function partition($collection, callable ...$callbacks) diff --git a/src/Functional/Pick.php b/src/Functional/Pick.php index b4be3c13..baf1b127 100644 --- a/src/Functional/Pick.php +++ b/src/Functional/Pick.php @@ -17,11 +17,17 @@ * Pick a single element from a collection of objects or arrays by index. * If no such index exists, return the default value. * - * @param ArrayAccess|array $collection - * @param mixed $index - * @param mixed $default - * @param callable|null $callback Custom function to check if index exists - * @return mixed + * @template K of array-key + * @template V + * @template D + * + * @param array $collection + * @param K $index + * @param D $default + * @param null|callable(iterable, K):mixed $callback Custom function to check if index exists + * + * @return D|V + * * @no-named-arguments */ function pick($collection, $index, $default = null, callable $callback = null) diff --git a/src/Functional/Pluck.php b/src/Functional/Pluck.php index dd8f6c24..06b34cbf 100644 --- a/src/Functional/Pluck.php +++ b/src/Functional/Pluck.php @@ -12,14 +12,17 @@ use ArrayAccess; use Functional\Exceptions\InvalidArgumentException; -use Traversable; /** * Extract a property from a collection of objects. * - * @param Traversable|array $collection + * @template K of array-key + * + * @param iterable $collection * @param string $propertyName - * @return array + * + * @return (K is numeric-string ? array : array) + * * @no-named-arguments */ function pluck($collection, $propertyName) diff --git a/src/Functional/Poll.php b/src/Functional/Poll.php index 7c632d77..1832ec42 100644 --- a/src/Functional/Poll.php +++ b/src/Functional/Poll.php @@ -14,19 +14,23 @@ use ArrayIterator; use Functional\Exceptions\InvalidArgumentException; use InfiniteIterator; -use Traversable; /** * Retry a callback until it returns a truthy value or the timeout (in microseconds) is reached * - * @param callable $callback - * @param integer $timeout Timeout in microseconds - * @param Traversable|null $delaySequence Default: no delay between calls - * @throws InvalidArgumentException - * @return boolean + * @template R + * + * @param callable(int,int):R $callback + * @param non-negative-int $timeout Timeout in microseconds + * @param null|\Iterator $delaySequence Default: no delay between calls + * + * @return false|R + * * @no-named-arguments + *@throws InvalidArgumentException + * */ -function poll(callable $callback, $timeout, Traversable $delaySequence = null) +function poll(callable $callback, $timeout, \Iterator $delaySequence = null) { InvalidArgumentException::assertIntegerGreaterThanOrEqual($timeout, 0, __FUNCTION__, 2); @@ -57,4 +61,6 @@ function poll(callable $callback, $timeout, Traversable $delaySequence = null) ++$retry; } + + return false; } diff --git a/src/Functional/Product.php b/src/Functional/Product.php index 6421b68a..6f324533 100644 --- a/src/Functional/Product.php +++ b/src/Functional/Product.php @@ -11,14 +11,18 @@ namespace Functional; use Functional\Exceptions\InvalidArgumentException; -use Traversable; /** * Takes a collection and returns the product of all elements * - * @param Traversable|array $collection - * @param integer|float $initial - * @return integer|float + * @template V of int|float + * @template I of int|float + * + * @param iterable $collection + * @param I $initial + * + * @return (V is int ? ($initial is int ? int : float) : float) + * * @no-named-arguments */ function product($collection, $initial = 1) diff --git a/src/Functional/Ratio.php b/src/Functional/Ratio.php index b9ee83e4..c81a850a 100644 --- a/src/Functional/Ratio.php +++ b/src/Functional/Ratio.php @@ -11,14 +11,18 @@ namespace Functional; use Functional\Exceptions\InvalidArgumentException; -use Traversable; /** * Takes a collection and returns the quotient of all elements * - * @param Traversable|array $collection - * @param integer|float $initial - * @return integer|float + * @template V of int|float + * @template I of int|float + * + * @param iterable $collection + * @param I $initial + * + * @return (V is int ? ($initial is int ? int|float : float) : float) + * * @no-named-arguments */ function ratio($collection, $initial = 1) diff --git a/src/Functional/ReduceLeft.php b/src/Functional/ReduceLeft.php index bce30c09..0e1d25a1 100644 --- a/src/Functional/ReduceLeft.php +++ b/src/Functional/ReduceLeft.php @@ -11,13 +11,18 @@ namespace Functional; use Functional\Exceptions\InvalidArgumentException; -use Traversable; /** - * @param Traversable|array $collection - * @param callable $callback - * @param mixed $initial - * @return mixed + * @template K + * @template V + * @template V2 + * + * @param iterable $collection + * @param callable(V,K,iterable,V2):V2 $callback + * @param V2 $initial + * + * @return V2 + * * @no-named-arguments */ function reduce_left($collection, callable $callback, $initial = null) diff --git a/src/Functional/ReduceRight.php b/src/Functional/ReduceRight.php index 094d570d..d0fe4062 100644 --- a/src/Functional/ReduceRight.php +++ b/src/Functional/ReduceRight.php @@ -11,13 +11,18 @@ namespace Functional; use Functional\Exceptions\InvalidArgumentException; -use Traversable; /** - * @param Traversable|array $collection - * @param callable $callback - * @param mixed $initial - * @return mixed + * @template K + * @template V + * @template V2 + * + * @param iterable $collection + * @param callable(V,K,iterable,V2):V2 $callback + * @param V2 $initial + * + * @return V2 + * * @no-named-arguments */ function reduce_right($collection, callable $callback, $initial = null) @@ -29,6 +34,10 @@ function reduce_right($collection, callable $callback, $initial = null) $data[] = [$index, $value]; } + if (0 === count($data)) { + return $initial; + } + while ((list($index, $value) = \array_pop($data))) { $initial = $callback($value, $index, $collection, $initial); } diff --git a/src/Functional/Reindex.php b/src/Functional/Reindex.php index ba6cbdf9..f58cc43e 100644 --- a/src/Functional/Reindex.php +++ b/src/Functional/Reindex.php @@ -11,15 +11,20 @@ namespace Functional; use Functional\Exceptions\InvalidArgumentException; -use Traversable; /** * Produces a new array of elements by assigning the values to keys generated by a transformation function (callback). * Callback arguments will be element, index, collection * - * @param Traversable|array $collection - * @param callable $callback - * @return array + * @template K + * @template V + * @template K2 of array-key + * + * @param iterable $collection + * @param callable(V,K,iterable):K2 $callback + * + * @return array + * * @no-named-arguments */ function reindex($collection, callable $callback) diff --git a/src/Functional/Reject.php b/src/Functional/Reject.php index 505acc91..732ea4c1 100644 --- a/src/Functional/Reject.php +++ b/src/Functional/Reject.php @@ -11,15 +11,20 @@ namespace Functional; use Functional\Exceptions\InvalidArgumentException; -use Traversable; /** - * Returns the elements in list without the elements that the truthy test (callback) passes. The opposite of - * Functional\select(). Callback arguments will be element, index, collection + * Returns the elements in list without the elements that the truthy test (callback) passes. + * The opposite of Functional\select(). + * Callback arguments will be element, index, collection + * + * @template K of array-key + * @template V + * + * @param iterable $collection + * @param null|callable(V,K,iterable):mixed $callback + * + * @return (K is numeric-string ? array : array) * - * @param Traversable|array $collection - * @param callable|null $callback - * @return array * @no-named-arguments */ function reject($collection, callable $callback = null) @@ -28,12 +33,8 @@ function reject($collection, callable $callback = null) $aggregation = []; - if ($callback === null) { - $callback = '\Functional\id'; - } - foreach ($collection as $index => $element) { - if (!$callback($element, $index, $collection)) { + if (!(null === $callback ? id($element) : $callback($element, $index, $collection))) { $aggregation[$index] = $element; } } diff --git a/src/Functional/Repeat.php b/src/Functional/Repeat.php index a3d00b95..de2d6d72 100644 --- a/src/Functional/Repeat.php +++ b/src/Functional/Repeat.php @@ -10,15 +10,15 @@ namespace Functional; -use Closure; use Functional\Exceptions\InvalidArgumentException; /** * Creates a function that can be used to repeat the execution of $callback. * - * @param callable $callback + * @param callable():mixed $callback + * + * @return callable(non-negative-int):void * - * @return Closure * @no-named-arguments */ function repeat(callable $callback) diff --git a/src/Functional/Retry.php b/src/Functional/Retry.php index 40ef0fa7..d42c935e 100644 --- a/src/Functional/Retry.php +++ b/src/Functional/Retry.php @@ -16,20 +16,25 @@ use Exception; use InfiniteIterator; use LimitIterator; -use Traversable; /** * Retry a callback until the number of retries are reached or the callback does no longer throw an exception * - * @param callable $callback - * @param integer $retries - * @param Traversable|null $delaySequence Default: no delay between calls + * @template R + * + * @param callable(int,int):R $callback + * @param int<-1,max> $retries + * @param null|\Iterator $delaySequence Default: no delay between calls + * * @throws Exception Any exception thrown by the callback * @throws InvalidArgumentException - * @return mixed Return value of the function + * @throws \LogicException Reached the end of execution before retries number and before success (should not happen) + * + * @return R Return value of the function + * * @no-named-arguments */ -function retry(callable $callback, $retries, Traversable $delaySequence = null) +function retry(callable $callback, $retries, \Iterator $delaySequence = null) { InvalidArgumentException::assertIntegerGreaterThanOrEqual($retries, 1, __FUNCTION__, 2); @@ -58,4 +63,6 @@ function retry(callable $callback, $retries, Traversable $delaySequence = null) ++$retry; } + + throw new \LogicException(); } diff --git a/src/Functional/Select.php b/src/Functional/Select.php index 93420357..a601d654 100644 --- a/src/Functional/Select.php +++ b/src/Functional/Select.php @@ -11,15 +11,19 @@ namespace Functional; use Functional\Exceptions\InvalidArgumentException; -use Traversable; /** * Looks through each element in the list, returning an array of all the elements that pass a truthy test (callback). * Opposite is Functional\reject(). Callback arguments will be element, index, collection * - * @param Traversable|array $collection - * @param callable|null $callback - * @return array + * @template K of array-key + * @template V + * + * @param iterable $collection + * @param callable(V,K,iterable):mixed $callback + * + * @return (K is numeric-string ? array : array) + * * @no-named-arguments */ function select($collection, callable $callback = null) @@ -28,12 +32,8 @@ function select($collection, callable $callback = null) $aggregation = []; - if ($callback === null) { - $callback = '\Functional\id'; - } - foreach ($collection as $index => $element) { - if ($callback($element, $index, $collection)) { + if (null === $callback ? id($element) : $callback($element, $index, $collection)) { $aggregation[$index] = $element; } } diff --git a/src/Functional/SelectKeys.php b/src/Functional/SelectKeys.php index b222631d..eb8f94f3 100644 --- a/src/Functional/SelectKeys.php +++ b/src/Functional/SelectKeys.php @@ -16,9 +16,14 @@ /** * Select the specified keys from the array * - * @param Traversable|array $collection - * @param array $keys - * @return array + * @template K of array-key + * @template V + * + * @param iterable $collection + * @param array $keys + * + * @return array + * * @no-named-arguments */ function select_keys($collection, array $keys) diff --git a/src/Functional/SequenceConstant.php b/src/Functional/SequenceConstant.php index 568dd86d..6d19c85b 100644 --- a/src/Functional/SequenceConstant.php +++ b/src/Functional/SequenceConstant.php @@ -13,13 +13,14 @@ use ArrayIterator; use Functional\Exceptions\InvalidArgumentException; use InfiniteIterator; -use Traversable; /** * Returns an infinite, traversable sequence of constant values * - * @param integer $value - * @return Traversable + * @param int<0,max> $value + * + * @return \Iterator + * * @no-named-arguments */ function sequence_constant($value) diff --git a/src/Functional/SequenceExponential.php b/src/Functional/SequenceExponential.php index 8e5fc629..77ee2937 100644 --- a/src/Functional/SequenceExponential.php +++ b/src/Functional/SequenceExponential.php @@ -16,10 +16,13 @@ /** * Returns an infinite, traversable sequence that exponentially grows by given percentage * - * @param integer $start - * @param integer $percentage Integer between 1 and 100 + * @param int<1,max> $start + * @param int<1,100> $percentage Integer between 1 and 100 + * * @return ExponentialSequence + * * @throws InvalidArgumentException + * * @no-named-arguments */ function sequence_exponential($start, $percentage) diff --git a/src/Functional/SequenceLinear.php b/src/Functional/SequenceLinear.php index 822a5794..44b5472a 100644 --- a/src/Functional/SequenceLinear.php +++ b/src/Functional/SequenceLinear.php @@ -12,14 +12,15 @@ use Functional\Exceptions\InvalidArgumentException; use Functional\Sequences\LinearSequence; -use Traversable; /** * Returns an infinite, traversable sequence that linearly grows by given amount * - * @param integer $start - * @param integer $amount - * @return Traversable + * @param int<0,max> $start + * @param int $amount + * + * @return LinearSequence + * * @no-named-arguments */ function sequence_linear($start, $amount) diff --git a/src/Functional/Some.php b/src/Functional/Some.php index df27e0a8..f55fb3ee 100644 --- a/src/Functional/Some.php +++ b/src/Functional/Some.php @@ -11,27 +11,27 @@ namespace Functional; use Functional\Exceptions\InvalidArgumentException; -use Traversable; /** * Returns true if some of the elements in the collection pass the callback truthy test. Short-circuits and stops * traversing the collection if a truthy element is found. Callback arguments will be value, index, collection * - * @param Traversable|array $collection - * @param callable|null $callback + * @template K + * @template V + * + * @param iterable $collection + * @param callable(V,K,iterable):mixed $callback + * * @return bool + * * @no-named-arguments */ function some($collection, callable $callback = null) { InvalidArgumentException::assertCollection($collection, __FUNCTION__, 1); - if ($callback === null) { - $callback = '\Functional\id'; - } - foreach ($collection as $index => $element) { - if ($callback($element, $index, $collection)) { + if (null === $callback ? id($element) : $callback($element, $index, $collection)) { return true; } } diff --git a/src/Functional/Sort.php b/src/Functional/Sort.php index 8dcc32ea..4c85da48 100644 --- a/src/Functional/Sort.php +++ b/src/Functional/Sort.php @@ -16,10 +16,15 @@ /** * Sorts a collection with a user-defined function, optionally preserving array keys * - * @param Traversable|array $collection - * @param callable $callback + * @template K of array-key + * @template V + * + * @param iterable $collection + * @param callable(V,V,iterable):int $callback * @param bool $preserveKeys - * @return array + * + * @return ($preserveKeys is true ? array : list) + * * @no-named-arguments */ function sort($collection, callable $callback, $preserveKeys = false) diff --git a/src/Functional/Sum.php b/src/Functional/Sum.php index e0f478b9..7763d626 100644 --- a/src/Functional/Sum.php +++ b/src/Functional/Sum.php @@ -11,14 +11,18 @@ namespace Functional; use Functional\Exceptions\InvalidArgumentException; -use Traversable; /** * Takes a collection and returns the sum of the elements * - * @param Traversable|array $collection - * @param integer|float $initial - * @return integer|float + * @template K + * @template V of int|float + * + * @param iterable $collection + * @param V $initial + * + * @return V + * * @no-named-arguments */ function sum($collection, $initial = 0) diff --git a/src/Functional/SuppressError.php b/src/Functional/SuppressError.php index 49baed2f..b6e5acc7 100644 --- a/src/Functional/SuppressError.php +++ b/src/Functional/SuppressError.php @@ -17,9 +17,15 @@ /** * Takes a function and returns a new function that wraps the callback and suppresses the PHP error * - * @param callable $callback + * @template V + * @template R + * + * @param callable(V...):R $callback + * * @throws ErrorException Throws exception if PHP error happened - * @return mixed + * + * @return callable(V...):R + * * @no-named-arguments */ function suppress_error(callable $callback) diff --git a/src/Functional/Tail.php b/src/Functional/Tail.php index 495131d2..c378204b 100644 --- a/src/Functional/Tail.php +++ b/src/Functional/Tail.php @@ -11,15 +11,19 @@ namespace Functional; use Functional\Exceptions\InvalidArgumentException; -use Traversable; /** * Returns all items from $collection except first element (head). Preserves $collection keys. * Takes an optional callback for filtering the collection. * - * @param Traversable|array $collection - * @param callable $callback - * @return array + * @template K of array-key + * @template V + * + * @param iterable $collection + * @param callable(V,K,iterable):mixed $callback + * + * @return (K is numeric-string ? array : array) + * * @no-named-arguments */ function tail($collection, callable $callback = null) @@ -35,7 +39,7 @@ function tail($collection, callable $callback = null) continue; } - if (!$callback || $callback($element, $index, $collection)) { + if (null === $callback || $callback($element, $index, $collection)) { $tail[$index] = $element; } } diff --git a/src/Functional/TailRecursion.php b/src/Functional/TailRecursion.php index 2fd548a0..4e526f91 100644 --- a/src/Functional/TailRecursion.php +++ b/src/Functional/TailRecursion.php @@ -16,8 +16,13 @@ * I took the solution from here https://gist.github.com/beberlei/4145442 * but reworked it and made without classes. * - * @param callable $fn - * @return callable + * @template V + * @template R + * + * @param callable(V...):R $fn + * + * @return callable(V...):(null|R) + * * @no-named-arguments */ function tail_recursion(callable $fn): callable diff --git a/src/Functional/TakeLeft.php b/src/Functional/TakeLeft.php index 2520877e..970ddd31 100644 --- a/src/Functional/TakeLeft.php +++ b/src/Functional/TakeLeft.php @@ -11,16 +11,19 @@ namespace Functional; use Functional\Exceptions\InvalidArgumentException; -use Traversable; /** * Creates a slice of $collection with $count elements taken from the beginning. If the collection has less than $count * elements, the whole collection will be returned as an array. * - * @param Traversable|array $collection + * @template K of array-key + * @template V + * + * @param iterable $collection * @param int $count * - * @return array + * @return array + * * @no-named-arguments */ function take_left($collection, $count) diff --git a/src/Functional/TakeRight.php b/src/Functional/TakeRight.php index c7af137b..55e146c3 100644 --- a/src/Functional/TakeRight.php +++ b/src/Functional/TakeRight.php @@ -11,7 +11,6 @@ namespace Functional; use Functional\Exceptions\InvalidArgumentException; -use Traversable; /** * Creates a slice of $collection with $count elements taken from the end. If the collection has less than $count @@ -19,11 +18,16 @@ * This function will reorder and reset the integer array indices by default. This behaviour can be changed by setting * preserveKeys to TRUE. String keys are always preserved, regardless of this parameter. * - * @param Traversable|array $collection + * + * @template K of array-key + * @template V + * + * @param iterable $collection * @param int $count * @param bool $preserveKeys * - * @return array + * @return array + * * @no-named-arguments */ function take_right($collection, $count, $preserveKeys = false) diff --git a/src/Functional/Tap.php b/src/Functional/Tap.php index a9322e84..33c643d7 100644 --- a/src/Functional/Tap.php +++ b/src/Functional/Tap.php @@ -13,9 +13,13 @@ /** * Call the given Closure with the given value, then return the value. * - * @param mixed $value - * @param callable $callback - * @return mixed + * @template V + * + * @param V $value + * @param callable(V):mixed $callback + * + * @return V + * * @no-named-arguments */ function tap($value, callable $callback) diff --git a/src/Functional/True.php b/src/Functional/True.php index 8013c8f4..027e1759 100644 --- a/src/Functional/True.php +++ b/src/Functional/True.php @@ -11,13 +11,14 @@ namespace Functional; use Functional\Exceptions\InvalidArgumentException; -use Traversable; /** * Returns true if all elements of the collection are strictly true * - * @param Traversable|array $collection + * @param iterable $collection + * * @return bool + * * @no-named-arguments */ function true($collection) diff --git a/src/Functional/Truthy.php b/src/Functional/Truthy.php index d38ef546..c1fa8e4a 100644 --- a/src/Functional/Truthy.php +++ b/src/Functional/Truthy.php @@ -11,13 +11,14 @@ namespace Functional; use Functional\Exceptions\InvalidArgumentException; -use Traversable; /** * Returns true if all elements of the collection evaluate to true * - * @param Traversable|array $collection + * @param iterable $collection + * * @return bool + * * @no-named-arguments */ function truthy($collection) diff --git a/src/Functional/Unique.php b/src/Functional/Unique.php index 656ac2be..6f281d23 100644 --- a/src/Functional/Unique.php +++ b/src/Functional/Unique.php @@ -11,15 +11,19 @@ namespace Functional; use Functional\Exceptions\InvalidArgumentException; -use Traversable; /** * Returns an array of unique elements * - * @param Traversable|array $collection - * @param callable $callback + * @template K of array-key + * @template V + * + * @param iterable $collection + * @param null|callable(V,K,iterable):mixed $callback * @param bool $strict - * @return array + * + * @return (K is numeric-string ? array : array) + * * @no-named-arguments */ function unique($collection, callable $callback = null, $strict = true) diff --git a/src/Functional/ValueToKey.php b/src/Functional/ValueToKey.php index 345723f7..2d559472 100644 --- a/src/Functional/ValueToKey.php +++ b/src/Functional/ValueToKey.php @@ -14,8 +14,6 @@ use Traversable; use WeakReference; -use function serialize; - use const PHP_VERSION_ID; /** diff --git a/src/Functional/With.php b/src/Functional/With.php index 0c00ddd3..374d033b 100644 --- a/src/Functional/With.php +++ b/src/Functional/With.php @@ -15,10 +15,16 @@ /** * Invoke a callback on a value if the value is not null * - * @param mixed $value - * @param callable $callback - * @param mixed $default The default value to return if $value is null - * @return mixed + * @template V + * @template V2 + * @template V3 + * + * @param V|null $value + * @param callable(V):V2 $callback + * @param V3 $default The default value to return if $value is null + * + * @return ($value is null ? V3 : V2) + * * @no-named-arguments */ function with($value, callable $callback, $default = null) diff --git a/src/Functional/Zip.php b/src/Functional/Zip.php index 23abf2e0..30cbf757 100644 --- a/src/Functional/Zip.php +++ b/src/Functional/Zip.php @@ -11,13 +11,18 @@ namespace Functional; use Functional\Exceptions\InvalidArgumentException; -use Traversable; /** * Recombines arrays by index and applies a callback optionally * - * @param array|Traversable ...$args One or more callbacks - * @return array + * @template K of array-key + * @template V + * @template Z + * + * @param iterable|callable(V...):Z ...$args One or more callbacks + * + * @return (K is numeric-string ? array : array) + * * @no-named-arguments */ function zip(...$args) diff --git a/src/Functional/ZipAll.php b/src/Functional/ZipAll.php index d8c95e20..4dda90b5 100644 --- a/src/Functional/ZipAll.php +++ b/src/Functional/ZipAll.php @@ -11,7 +11,6 @@ namespace Functional; use Functional\Exceptions\InvalidArgumentException; -use Traversable; /** * Recombines arrays by index (column) and applies a callback optionally @@ -19,8 +18,10 @@ * When the input collections are different lengths the resulting collections * will all have the length which is required to fit all the keys * - * @param array|Traversable ...$args One or more callbacks - * @return array + * @param iterable ...$args One or more callbacks + * + * @return array + * * @no-named-arguments */ function zip_all(...$args)