Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: unfold constructor is not variadic anymore #269

Merged
merged 1 commit into from
Nov 4, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
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
14 changes: 9 additions & 5 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 of T
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure why this is needed - doesn't it work if we leave it like before, just T ? Either way I guess it's the same thing

Copy link
Collaborator Author

@drupol drupol Nov 4, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nope it doesn't work. This is a static function, so, U must be defined locally at the method level. And U is going to be made of T.

*
* @param callable(T ...): list<T> $callback
* @param T ...$parameters
* @param callable(U ...): list<U> $callback
* @param array<int, U> $parameters
*
* @return Collection<int, list<T>>
* @return Collection<int, list<U>>
*/
public static function unfold(callable $callback, ...$parameters): Collection;
public static function unfold(callable $callback, array $parameters = []): Collection;
}
6 changes: 3 additions & 3 deletions src/Operation/Unfold.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,17 +16,17 @@
final class Unfold extends AbstractOperation
{
/**
* @return Closure(T...): Closure(callable(T...): list<T>): Closure(): Generator<int, list<T>>
* @return Closure(array<int, T>): Closure(callable(T...): list<T>): Closure(): Generator<int, list<T>>
*/
public function __invoke(): Closure
{
return
/**
* @param T ...$parameters
* @param array<int, T> $parameters
*
* @return Closure(callable(T...): list<T>): Closure(): Generator<int, list<T>>
*/
static fn (...$parameters): Closure =>
static fn ($parameters): Closure =>
/**
* @param callable(T...): list<T> $callback
*
Expand Down
15 changes: 8 additions & 7 deletions tests/static-analysis/unfold.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,17 +24,18 @@ 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)
);
}
}