Skip to content

Commit

Permalink
Merge branch 'develop'
Browse files Browse the repository at this point in the history
* develop:
  specify next release
  add Either::eitherWay()
  add Maybe::eitherWay()
  add Maybe::toSequence()
  add Either::flip()
  • Loading branch information
Baptouuuu committed Apr 29, 2023
2 parents 71b06b8 + 67ca51a commit a15d1e4
Show file tree
Hide file tree
Showing 15 changed files with 458 additions and 0 deletions.
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,14 @@
# Changelog

## 4.14.0 - 2023-04-29

### Added

- `Innmind\Immutable\Either::flip()`
- `Innmind\Immutable\Maybe::toSequence()`
- `Innmind\Immutable\Maybe::eitherWay()`
- `Innmind\Immutable\Either::eitherWay()`

## 4.13.0 - 2023-04-10

### Added
Expand Down
38 changes: 38 additions & 0 deletions docs/EITHER.md
Original file line number Diff line number Diff line change
Expand Up @@ -189,3 +189,41 @@ Either::defer(function() {
static fn() => null,
);
```

## `->flip()`

This method changes the side of the value contained in the `Either`. This is useful when you want to only keep the error and discard the right value you would use like this:

```php
/**
* @return Either<SomeError, SomeData>
*/
function foo() { /*...*/}

$error = foo() // returns type Either<SomeError, SomeData>
->flip() // returns type Either<SomeData, SomeError>
->maybe(); // returns type Maybe<SomeError>
```

## `->eitherWay()`

This method is kind of combines both `flatMap` and `otherwise` in a single call. This is useful when you can't call `otherwise` after `flatMap` because you don't want to override the left value returned by `flatMap`.

```php
/**
* @return Either<SomeError, SideEffect> SideEffect when on macOS
*/
function isMac(): Either { /* ... */}
/**
* @return Either<SomeError, SideEffect>
*/
function runMac(): Either { /* ... */ }
/**
* @return Either<SomeError, SideEffect>
*/
function runLinux(): Either { /* ... */ }

$_ = isMac()->eitherWay(runMac(...), runLinux(...));
```

In this case we want to run `runLinux` only when `isMac` returns a `SideEffect` which is possible thanks to `->eitherWay()`. Contrary to `isMac()->flatMap(runMac(...))->otherwise(runLinux(...))` that could lead to `runLinux` to be called if `runMac` returns an error.
44 changes: 44 additions & 0 deletions docs/MAYBE.md
Original file line number Diff line number Diff line change
Expand Up @@ -180,3 +180,47 @@ Maybe::defer(function() {
static fn() => null,
);
```

## `->toSequence()`

This method will return a `Sequence` with one or no value. This can be useful when "`flatMap`ping" a `Sequence` like this:

```php
$vars = Sequence::of('DB_URL', 'MAILER_URL', /* and so on */)
->flatMap(static fn($var) => env($var)->toSequence());
```

> **Note** this example uses the `env` function defined at the start of this documentation.
This is equivalent to:

```php
$vars = Sequence::of('DB_URL', 'MAILER_URL', /* and so on */)
->flatMap(static fn($var) => env($var)->match(
static fn($value) => Sequence::of($value),
static fn() => Sequence::of(),
));
```

## `->eitherWay()`

This method is kind of combines both `flatMap` and `otherwise` in a single call. This is useful when you can't call `otherwise` after `flatMap` because you don't want to override the _nothingness_ returned by `flatMap`.

```php
/**
* @return Maybe<SideEffect> SideEffect when on macOS
*/
function isMac(): Maybe { /* ... */}
/**
* @return Maybe<SideEffect>
*/
function runMac(): Maybe { /* ... */ }
/**
* @return Maybe<SideEffect>
*/
function runLinux(): Maybe { /* ... */ }

$_ = isMac()->eitherWay(runMac(...), runLinux(...));
```

In this case we want to run `runLinux` only when `isMac` returns nothing which is possible thanks to `->eitherWay()`. Contrary to `isMac()->flatMap(runMac(...))->otherwise(runLinux(...))` that could lead to `runLinux` to be called if `runMac` returns nothing.
24 changes: 24 additions & 0 deletions src/Either.php
Original file line number Diff line number Diff line change
Expand Up @@ -165,4 +165,28 @@ public function memoize(): self
{
return $this->either->memoize();
}

/**
* Switch the sides of the values, left becomes right and right left
*
* @return self<R, L>
*/
public function flip(): self
{
return new self($this->either->flip());
}

/**
* @template A
* @template B
*
* @param callable(R): self<A, B> $right
* @param callable(L): self<A, B> $left
*
* @return self<A, B>
*/
public function eitherWay(callable $right, callable $left): self
{
return $this->either->eitherWay($right, $left);
}
}
10 changes: 10 additions & 0 deletions src/Either/Defer.php
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,16 @@ public function memoize(): Either
return $this->unwrap();
}

public function flip(): self
{
return new self(fn() => $this->unwrap()->flip());
}

public function eitherWay(callable $right, callable $left): Either
{
return Either::defer(fn() => $this->unwrap()->eitherWay($right, $left));
}

/**
* @return Either<L1, R1>
*/
Expand Down
16 changes: 16 additions & 0 deletions src/Either/Implementation.php
Original file line number Diff line number Diff line change
Expand Up @@ -83,4 +83,20 @@ public function maybe(): Maybe;
* @return Either<L, R>
*/
public function memoize(): Either;

/**
* @return self<R, L>
*/
public function flip(): self;

/**
* @template A
* @template B
*
* @param callable(R): Either<A, B> $right
* @param callable(L): Either<A, B> $left
*
* @return Either<A, B>
*/
public function eitherWay(callable $right, callable $left): Either;
}
11 changes: 11 additions & 0 deletions src/Either/Left.php
Original file line number Diff line number Diff line change
Expand Up @@ -81,4 +81,15 @@ public function memoize(): Either
{
return Either::left($this->value);
}

public function flip(): Implementation
{
return new Right($this->value);
}

public function eitherWay(callable $right, callable $left): Either
{
/** @psalm-suppress ImpureFunctionCall */
return $left($this->value);
}
}
11 changes: 11 additions & 0 deletions src/Either/Right.php
Original file line number Diff line number Diff line change
Expand Up @@ -87,4 +87,15 @@ public function memoize(): Either
{
return Either::right($this->value);
}

public function flip(): Implementation
{
return new Left($this->value);
}

public function eitherWay(callable $right, callable $left): Either
{
/** @psalm-suppress ImpureFunctionCall */
return $right($this->value);
}
}
21 changes: 21 additions & 0 deletions src/Maybe.php
Original file line number Diff line number Diff line change
Expand Up @@ -194,4 +194,25 @@ public function memoize(): self
{
return $this->maybe->memoize();
}

/**
* @return Sequence<T>
*/
public function toSequence(): Sequence
{
return $this->maybe->toSequence();
}

/**
* @template V
*
* @param callable(T): self<V> $just
* @param callable(): self<V> $nothing
*
* @return self<V>
*/
public function eitherWay(callable $just, callable $nothing): self
{
return $this->maybe->eitherWay($just, $nothing);
}
}
14 changes: 14 additions & 0 deletions src/Maybe/Defer.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
use Innmind\Immutable\{
Maybe,
Either,
Sequence,
};

/**
Expand Down Expand Up @@ -67,6 +68,19 @@ public function memoize(): Maybe
return $this->unwrap();
}

public function toSequence(): Sequence
{
/** @psalm-suppress ImpureFunctionCall */
return Sequence::defer((function() {
yield from $this->unwrap()->toSequence()->toList();
})());
}

public function eitherWay(callable $just, callable $nothing): Maybe
{
return Maybe::defer(fn() => $this->unwrap()->eitherWay($just, $nothing));
}

/**
* @return Maybe<V>
*/
Expand Down
16 changes: 16 additions & 0 deletions src/Maybe/Implementation.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
use Innmind\Immutable\{
Maybe,
Either,
Sequence,
};

/**
Expand Down Expand Up @@ -68,4 +69,19 @@ public function either(): Either;
* @return Maybe<T>
*/
public function memoize(): Maybe;

/**
* @return Sequence<T>
*/
public function toSequence(): Sequence;

/**
* @template V
*
* @param callable(T): Maybe<V> $just
* @param callable(): Maybe<V> $nothing
*
* @return Maybe<V>
*/
public function eitherWay(callable $just, callable $nothing): Maybe;
}
12 changes: 12 additions & 0 deletions src/Maybe/Just.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
use Innmind\Immutable\{
Maybe,
Either,
Sequence,
};

/**
Expand Down Expand Up @@ -72,4 +73,15 @@ public function memoize(): Maybe
{
return Maybe::just($this->value);
}

public function toSequence(): Sequence
{
return Sequence::of($this->value);
}

public function eitherWay(callable $just, callable $nothing): Maybe
{
/** @psalm-suppress ImpureFunctionCall */
return $just($this->value);
}
}
12 changes: 12 additions & 0 deletions src/Maybe/Nothing.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
use Innmind\Immutable\{
Maybe,
Either,
Sequence,
};

/**
Expand Down Expand Up @@ -55,4 +56,15 @@ public function memoize(): Maybe
/** @var Maybe<empty> */
return Maybe::nothing();
}

public function toSequence(): Sequence
{
return Sequence::of();
}

public function eitherWay(callable $just, callable $nothing): Maybe
{
/** @psalm-suppress ImpureFunctionCall */
return $nothing();
}
}
Loading

0 comments on commit a15d1e4

Please sign in to comment.