From cb660ae29a4c77dfc57f8f9e92786240c1858077 Mon Sep 17 00:00:00 2001 From: Pablo Largo Mohedano Date: Wed, 18 Oct 2023 15:56:20 +0200 Subject: [PATCH] feat(option): new `Option::merge()` method --- src/Psl/Option/Option.php | 19 +++++++++++++++++++ tests/unit/Option/NoneTest.php | 21 +++++++++++++++++++++ tests/unit/Option/SomeTest.php | 8 ++++++++ 3 files changed, 48 insertions(+) diff --git a/src/Psl/Option/Option.php b/src/Psl/Option/Option.php index d7dc521f..89c4ddb7 100644 --- a/src/Psl/Option/Option.php +++ b/src/Psl/Option/Option.php @@ -279,4 +279,23 @@ public function mapOrElse(Closure $closure, Closure $default): Option return some($default()); } + + /** + * Merges an `Option` and other `Option` to `Option` by applying a function to both contained values. + * + * @template Tu + * + * @param Option $other + * @param (Closure(T, T): Tu) $closure + * + * @return Option + */ + public function merge(Option $other, Closure $closure) + { + if ($this->option !== null && $other->option !== null) { + return some($closure($this->option[0], $other->option[0])); + } + + return none(); + } } diff --git a/tests/unit/Option/NoneTest.php b/tests/unit/Option/NoneTest.php index 7a4c73dc..1c85af3b 100644 --- a/tests/unit/Option/NoneTest.php +++ b/tests/unit/Option/NoneTest.php @@ -108,4 +108,25 @@ public function testAndThen(): void static::assertNull($option->andThen(static fn($i) => Option\some($i + 1))->unwrapOr(null)); } + + /** + * @param Option\Option $value1 + * @param Option\Option $value2 + * + * @dataProvider provideMerge + */ + public function testMerge(Option\Option $value1, Option\Option $value2): void + { + $this->expectException(NoneException::class); + $this->expectExceptionMessage('Attempting to unwrap a none option.'); + + $value1->merge($value2, static fn($a, $b) => $a + $b)->unwrap(); + } + + public function provideMerge(): iterable + { + yield [Option\none(), Option\none()]; + yield [Option\none(), Option\some(2)]; + yield [Option\some(1), Option\none()]; + } } diff --git a/tests/unit/Option/SomeTest.php b/tests/unit/Option/SomeTest.php index 4b216f12..9b5b42e2 100644 --- a/tests/unit/Option/SomeTest.php +++ b/tests/unit/Option/SomeTest.php @@ -105,4 +105,12 @@ public function testAndThen(): void static::assertSame(3, $option->andThen(static fn($i) => Option\some($i + 1))->unwrapOr(null)); } + + public function testMerge(): void + { + $value1 = Option\some(1); + $value2 = Option\some(2); + + static::assertSame(3, $value1->merge($value2, static fn($a, $b) => $a + $b)->unwrap()); + } }