Skip to content

Commit

Permalink
refactor: unfold constructor is not variadic anymore
Browse files Browse the repository at this point in the history
  • Loading branch information
drupol committed Nov 3, 2022
1 parent dae9eb6 commit 335b3ec
Show file tree
Hide file tree
Showing 9 changed files with 36 additions and 19 deletions.
2 changes: 1 addition & 1 deletion docs/pages/api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ Create a collection by yielding from a callback with an initial value.
on the next callback call. Therefore, the returned list should contain values of the same type
as the parameters for the callback function.

Signature: ``Collection::unfold(callable $callback, ...$parameters): Collection;``
Signature: ``Collection::unfold(callable $callback, $parameters): Collection;``

.. literalinclude:: code/operations/unfold.php
:language: php
Expand Down
6 changes: 3 additions & 3 deletions docs/pages/code/operations/unfold.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
include __DIR__ . '/../../../../vendor/autoload.php';

// Example 1 -> A list of Naturals from 1 to Infinity (use `limit` to keep only a set of them)
Collection::unfold(static fn (int $n): array => [$n + 1], 1)
Collection::unfold(static fn (int $n): array => [$n + 1], [1])
->unwrap()
->all(); // [1, 2, 3, 4, ...]

Expand All @@ -22,8 +22,8 @@
->all(); // [1, 1, 2, 3, 5, 8, 13, 21, 34, 55]

// Example 3 -> infinite range, similar to the `range` operation
$even = Collection::unfold(static fn ($carry): array => [$carry + 2], -2)->unwrap();
$odd = Collection::unfold(static fn ($carry): array => [$carry + 2], -1)->unwrap();
$even = Collection::unfold(static fn ($carry): array => [$carry + 2], [-2])->unwrap();
$odd = Collection::unfold(static fn ($carry): array => [$carry + 2], [-1])->unwrap();

// Is the same as
$even = Collection::range(0, INF, 2);
Expand Down
5 changes: 5 additions & 0 deletions phpstan-baseline.neon
Original file line number Diff line number Diff line change
Expand Up @@ -460,6 +460,11 @@ parameters:
count: 1
path: src/Operation/Transpose.php

-
message: "#^Template type U of method loophp\\\\collection\\\\Operation\\\\Unfold\\:\\:__invoke\\(\\) is not referenced in a parameter\\.$#"
count: 1
path: src/Operation/Unfold.php

-
message: "#^While loop condition is always true\\.$#"
count: 1
Expand Down
4 changes: 2 additions & 2 deletions src/Collection.php
Original file line number Diff line number Diff line change
Expand Up @@ -890,9 +890,9 @@ public function truthy(): bool
return (new Truthy())()($this)->current();
}

public static function unfold(callable $callback, ...$parameters): CollectionInterface
public static function unfold(callable $callback, array $parameters = []): CollectionInterface
{
return new self((new Unfold())()(...$parameters)($callback));
return new self((new Unfold())()($parameters)($callback));
}

public function unlines(): string
Expand Down
1 change: 1 addition & 0 deletions src/Contract/Collection.php
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,7 @@
* @template-extends TakeWhileable<TKey, T>
* @template-extends Transposeable<TKey, T>
* @template-extends Truthyable<TKey, T>
* @template-extends Unfoldable<TKey, T>
* @template-extends Unlinesable<TKey, T>
* @template-extends Unpackable<mixed, array{0: TKey, 1: T}>
* @template-extends Unpairable<TKey, T>
Expand Down
12 changes: 8 additions & 4 deletions src/Contract/Operation/Unfoldable.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,23 @@

use loophp\collection\Contract\Collection;

/**
* @template TKey
* @template T
*/
interface Unfoldable
{
/**
* Create a collection by yielding from a callback with an initial value.
*
* @see https://loophp-collection.readthedocs.io/en/stable/pages/api.html#unfold
*
* @template T
* @template U
*
* @param callable(T ...): list<T> $callback
* @param T ...$parameters
* @param callable((T|U) ...): list<T> $callback
* @param array<int, U> $parameters
*
* @return Collection<int, list<T>>
*/
public static function unfold(callable $callback, ...$parameters): Collection;
public static function unfold(callable $callback, array $parameters = []): Collection;
}
12 changes: 7 additions & 5 deletions src/Operation/Unfold.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,19 +18,21 @@
final class Unfold extends AbstractOperation
{
/**
* @return Closure(T...): Closure(callable(T...): list<T>): Closure(): Generator<int, list<T>>
* @template U
*
* @return Closure(array<int, U>): Closure(callable((T|U)...): list<T>): Closure(): Generator<int, list<T>>
*/
public function __invoke(): Closure
{
return
/**
* @param T ...$parameters
* @param array<int, U> $parameters
*
* @return Closure(callable(T...): list<T>): Closure(): Generator<int, list<T>>
* @return Closure(callable((T|U)...): list<T>): Closure(): Generator<int, list<T>>
*/
static fn (...$parameters): Closure =>
static fn ($parameters): Closure =>
/**
* @param callable(T...): list<T> $callback
* @param callable((T|U)...): list<T> $callback
*
* @return Closure(): Generator<int, list<T>>
*/
Expand Down
11 changes: 8 additions & 3 deletions tests/static-analysis/unfold.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,17 +24,22 @@ function unfold_checkListOfLists(CollectionInterface $collection): void
$fib = static fn (int $a = 0, int $b = 1): array => [$b, $a + $b];

unfold_checkList(Collection::unfold($plusTwo)->unwrap());
unfold_checkList(Collection::unfold($plusTwo, -2)->unwrap());
unfold_checkList(Collection::unfold($plusTwo, [-2])->unwrap());

// VALID use cases -> PHPStan thinks the collection is of type Collection<int, array<int, mixed>>, but Psalm works

/** @phpstan-ignore-next-line */
unfold_checkListOfLists(Collection::unfold($plusTwo));
/** @phpstan-ignore-next-line */
/** @psalm-suppress InvalidArgument @phpstan-ignore-next-line */
unfold_checkListOfLists(Collection::unfold($plusTwo, -2));
/** @phpstan-ignore-next-line */
unfold_checkListOfLists(Collection::unfold($fib));
/** @phpstan-ignore-next-line */
/**
* @psalm-suppress InvalidArgument
* @psalm-suppress TooManyArguments
*
* @phpstan-ignore-next-line
*/
unfold_checkListOfLists(Collection::unfold($fib, 0, 1));

// VALID use case -> `Pluck` can return various things so analysers cannot know the type is correct
Expand Down
2 changes: 1 addition & 1 deletion tests/unit/CollectionConstructorsTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -307,7 +307,7 @@ public function testUnfoldConstructor(): void
{
$this::assertIdenticalIterable(
[[0], [2], [4], [6], [8]],
Collection::unfold(static fn (int $n): array => [$n + 2], -2)->limit(5)
Collection::unfold(static fn (int $n): array => [$n + 2], [-2])->limit(5)
);
}
}

0 comments on commit 335b3ec

Please sign in to comment.