Skip to content

Commit

Permalink
Merge branch 'develop'
Browse files Browse the repository at this point in the history
* develop:
  specify next release
  test against php 8.2
  support lazy and deferred Set flatMap
  expose the implementation of the flatmap
  • Loading branch information
Baptouuuu committed Dec 17, 2022
2 parents 8de9051 + 675092a commit 2f1ebbd
Show file tree
Hide file tree
Showing 13 changed files with 123 additions and 35 deletions.
6 changes: 3 additions & 3 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ jobs:
strategy:
matrix:
os: [ubuntu-latest, macOS-latest]
php-version: ['8.0', '8.1']
php-version: ['8.0', '8.1', '8.2']
name: 'PHPUnit'
steps:
- name: Checkout
Expand All @@ -30,7 +30,7 @@ jobs:
strategy:
matrix:
os: [ubuntu-latest, macOS-latest]
php-version: ['8.0', '8.1']
php-version: ['8.0', '8.1', '8.2']
name: 'Coverage'
steps:
- name: Checkout
Expand All @@ -54,7 +54,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
php-version: ['8.0', '8.1']
php-version: ['8.0', '8.1', '8.2']
name: 'Psalm'
steps:
- name: Checkout
Expand Down
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# Changelog

## 4.9.0 - 2022-12-17

### Changed

- Support lazy and deferred `Set::flatMap()`

## 4.8.0 - 2022-12-11

### Added
Expand Down
2 changes: 1 addition & 1 deletion src/Sequence.php
Original file line number Diff line number Diff line change
Expand Up @@ -411,7 +411,7 @@ public function flatMap(callable $map): self
/** @var callable(self<S>): Sequence\Implementation<S> */
$exfiltrate = static fn(self $sequence): Sequence\Implementation => $sequence->implementation;

return $this->implementation->flatMap($map, $exfiltrate);
return new self($this->implementation->flatMap($map, $exfiltrate));
}

/**
Expand Down
15 changes: 8 additions & 7 deletions src/Sequence/Defer.php
Original file line number Diff line number Diff line change
Expand Up @@ -327,22 +327,23 @@ public function map(callable $function): Implementation

/**
* @template S
* @template C of Sequence<S>|Set<S>
*
* @param callable(T): Sequence<S> $map
* @param callable(Sequence<S>): Implementation<S> $exfiltrate
* @param callable(T): C $map
* @param callable(C): Implementation<S> $exfiltrate
*
* @return Sequence<S>
* @return self<S>
*/
public function flatMap(callable $map, callable $exfiltrate): Sequence
public function flatMap(callable $map, callable $exfiltrate): self
{
/** @psalm-suppress ImpureFunctionCall */
return Sequence::defer(
return new self(
(static function(\Iterator $values, callable $map, callable $exfiltrate): \Generator {
/** @var T $value */
foreach ($values as $value) {
/**
* @var callable(T): Sequence<S> $map
* @var callable(Sequence<S>): Implementation<S> $exfiltrate
* @var callable(T): C $map
* @var callable(C): Implementation<S> $exfiltrate
*/
foreach ($exfiltrate($map($value))->iterator() as $inner) {
yield $inner;
Expand Down
9 changes: 5 additions & 4 deletions src/Sequence/Implementation.php
Original file line number Diff line number Diff line change
Expand Up @@ -164,13 +164,14 @@ public function map(callable $function): self;

/**
* @template S
* @template C of Sequence<S>|Set<S>
*
* @param callable(T): Sequence<S> $map
* @param callable(Sequence<S>): self<S> $exfiltrate
* @param callable(T): C $map
* @param callable(C): self<S> $exfiltrate
*
* @return Sequence<S>
* @return self<S>
*/
public function flatMap(callable $map, callable $exfiltrate): Sequence;
public function flatMap(callable $map, callable $exfiltrate): self;

/**
* Pad the sequence to a defined size with the given element
Expand Down
11 changes: 6 additions & 5 deletions src/Sequence/Lazy.php
Original file line number Diff line number Diff line change
Expand Up @@ -352,17 +352,18 @@ static function(callable $registerCleanup) use ($values, $function): \Generator

/**
* @template S
* @template C of Sequence<S>|Set<S>
*
* @param callable(T): Sequence<S> $map
* @param callable(Sequence<S>): Implementation<S> $exfiltrate
* @param callable(T): C $map
* @param callable(C): Implementation<S> $exfiltrate
*
* @return Sequence<S>
* @return self<S>
*/
public function flatMap(callable $map, callable $exfiltrate): Sequence
public function flatMap(callable $map, callable $exfiltrate): self
{
$values = $this->values;

return Sequence::lazy(
return new self(
static function(callable $registerCleanup) use ($values, $map, $exfiltrate): \Generator {
foreach ($values($registerCleanup) as $value) {
$generator = self::open(
Expand Down
17 changes: 10 additions & 7 deletions src/Sequence/Primitive.php
Original file line number Diff line number Diff line change
Expand Up @@ -256,21 +256,24 @@ public function map(callable $function): self

/**
* @template S
* @template C of Sequence<S>|Set<S>
*
* @param callable(T): Sequence<S> $map
* @param callable(Sequence<S>): Implementation<S> $exfiltrate
* @param callable(T): C $map
* @param callable(C): Implementation<S> $exfiltrate
*
* @return Sequence<S>
* @return Implementation<S>
*/
public function flatMap(callable $map, callable $exfiltrate): Sequence
public function flatMap(callable $map, callable $exfiltrate): Implementation
{
/**
* @psalm-suppress MixedArgument
* @var Sequence<S>
* @psalm-suppress InvalidArgument
* @psalm-suppress ImpureFunctionCall
* @var Implementation<S>
*/
return $this->reduce(
Sequence::of(),
static fn(Sequence $carry, $value) => $carry->append($map($value)),
new self,
static fn(self $carry, $value) => $carry->append($exfiltrate($map($value))),
);
}

Expand Down
12 changes: 4 additions & 8 deletions src/Set.php
Original file line number Diff line number Diff line change
Expand Up @@ -333,14 +333,10 @@ public function map(callable $function): self
*/
public function flatMap(callable $map): self
{
/**
* @psalm-suppress InvalidArgument
* @psalm-suppress MixedArgument
*/
return $this->reduce(
self::of(),
static fn(self $carry, $value) => $carry->merge($map($value)),
);
/** @var callable(self<S>): Sequence\Implementation<S> */
$exfiltrate = static fn(self $set): Sequence\Implementation => $set->implementation->sequence();

return new self($this->implementation->flatMap($map, $exfiltrate));
}

/**
Expand Down
13 changes: 13 additions & 0 deletions src/Set/Defer.php
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,19 @@ public function map(callable $function): self
return self::distinct($this->values->map($function));
}

/**
* @template S
*
* @param callable(T): Set<S> $map
* @param callable(Set<S>): Sequence\Implementation<S> $exfiltrate
*
* @return self<S>
*/
public function flatMap(callable $map, callable $exfiltrate): self
{
return self::distinct($this->values->flatMap($map, $exfiltrate));
}

/**
* @param callable(T): bool $predicate
*
Expand Down
10 changes: 10 additions & 0 deletions src/Set/Implementation.php
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,16 @@ public function groupBy(callable $discriminator): Map;
*/
public function map(callable $function): self;

/**
* @template S
*
* @param callable(T): Set<S> $map
* @param callable(Set<S>): Sequence\Implementation<S> $exfiltrate
*
* @return self<S>
*/
public function flatMap(callable $map, callable $exfiltrate): self;

/**
* Return a sequence of 2 sets partitioned according to the given predicate
*
Expand Down
13 changes: 13 additions & 0 deletions src/Set/Lazy.php
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,19 @@ public function map(callable $function): self
return self::distinct($this->values->map($function));
}

/**
* @template S
*
* @param callable(T): Set<S> $map
* @param callable(Set<S>): Sequence\Implementation<S> $exfiltrate
*
* @return self<S>
*/
public function flatMap(callable $map, callable $exfiltrate): self
{
return self::distinct($this->values->flatMap($map, $exfiltrate));
}

/**
* @param callable(T): bool $predicate
*
Expand Down
18 changes: 18 additions & 0 deletions src/Set/Primitive.php
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,24 @@ public function map(callable $function): self
return new self($this->values->map($function)->distinct());
}

/**
* @template S
*
* @param callable(T): Set<S> $map
* @param callable(Set<S>): Sequence\Implementation<S> $exfiltrate
*
* @return Implementation<S>
*/
public function flatMap(callable $map, callable $exfiltrate): Implementation
{
return new self(
$this
->values
->flatMap($map, $exfiltrate)
->distinct(),
);
}

/**
* @param callable(T): bool $predicate
*
Expand Down
26 changes: 26 additions & 0 deletions tests/SetTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -302,6 +302,32 @@ public function testFlatMap()
$this->assertNotSame($set, $set2);
$this->assertSame([1, 2, 3, 4], $set->toList());
$this->assertSame([1, 3, 2, 4, 5, 6], $set2->toList());

$loaded = false;
$set = Set::lazy(static function() use (&$loaded) {
yield 1;
yield 2;
yield 3;
$loaded = true;
})->flatMap(static fn($i) => Set::of($i, $i + 1));

$this->assertInstanceOf(Set::class, $set);
$this->assertFalse($loaded);
$this->assertSame([1, 2, 3, 4], $set->toList());
$this->assertTrue($loaded);

$loaded = false;
$set = Set::defer((static function() use (&$loaded) {
yield 1;
yield 2;
yield 3;
$loaded = true;
})())->flatMap(static fn($i) => Set::of($i, $i + 1));

$this->assertInstanceOf(Set::class, $set);
$this->assertFalse($loaded);
$this->assertSame([1, 2, 3, 4], $set->toList());
$this->assertTrue($loaded);
}

public function testPartition()
Expand Down

0 comments on commit 2f1ebbd

Please sign in to comment.