Skip to content

Commit

Permalink
Fix template type annotations to make more sense (#50)
Browse files Browse the repository at this point in the history
  • Loading branch information
muglug authored and GrahamCampbell committed Dec 15, 2019
1 parent 100a252 commit ea10a97
Show file tree
Hide file tree
Showing 5 changed files with 47 additions and 35 deletions.
5 changes: 2 additions & 3 deletions phpstan.tests.neon.dist
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@ parameters:
level: 5
ignoreErrors:
- '/Parameter \#1 \$callable of method PhpOption\\[a-zA-Z]+<[a-zA-Z]+>::getOrCall\(\) expects callable\(\)/'
- '/Parameter \#1 \$callback of class PhpOption\\[a-zA-Z]+ constructor expects callable\(\)/'
- '/Parameter \#1 \$callback of class PhpOption\\[a-zA-Z]+ constructor expects callable\(array<int, array<int, array<int, mixed>>>\)/'
- '/Parameter \#1 \$value of method PhpOption\\Some<string>::[a-z]+\(\) expects string/'
- '/Parameter \#1 \$callback of static method PhpOption\\LazyOption<mixed>::create\(\) expects callable\(\): mixed/'
- '#Parameter \#1 \$callable of method PhpOption\\[a-zA-Z]+<[a-z\|]+>::forAll\(\) expects callable\([a-z\|]+\): void, Closure\(mixed\): mixed given.#'
- '/Parameter \#1 \$callback of static method PhpOption\\LazyOption<mixed>::create\(\) expects callable\(array<int, array<int, array<int, array<int, array<int, mixed>>>>>\): PhpOption\\Option<mixed>/'
- '#Parameter \#1 \$array of static method PhpOption\\Option<mixed>::fromArraysValue\(\) expects array<string, mixed>\|ArrayAccess<string, mixed>\|null, string given.#'
13 changes: 6 additions & 7 deletions src/PhpOption/LazyOption.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,20 +25,19 @@
*/
final class LazyOption extends Option
{
/** @var callable */
/** @var callable(mixed...):(Option<T>) */
private $callback;

/** @var array */
/** @var array<int, mixed> */
private $arguments;

/** @var Option<T>|null */
private $option;

/**
* @template S
*
* @param callable $callback
* @param array $arguments
* @param callable(mixed...):(Option<S>) $callback
* @param array<int, mixed> $arguments
*
* @return LazyOption<S>
*/
Expand All @@ -48,8 +47,8 @@ public static function create($callback, array $arguments = [])
}

/**
* @param callable $callback
* @param array $arguments
* @param callable(mixed...):(Option<T>) $callback
* @param array<int, mixed> $arguments
*/
public function __construct($callback, array $arguments = [])
{
Expand Down
8 changes: 3 additions & 5 deletions src/PhpOption/None.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,17 +21,15 @@
use EmptyIterator;

/**
* @template T
*
* @extends Option<T>
* @extends Option<mixed>
*/
final class None extends Option
{
/** @var None<T> */
/** @var None|null */
private static $instance;

/**
* @return None<T>
* @return None
*/
public static function create()
{
Expand Down
50 changes: 32 additions & 18 deletions src/PhpOption/Option.php
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ public static function fromArraysValue($array, $key)
public static function fromReturn($callback, array $arguments = [], $noneValue = null)
{
return new LazyOption(function () use ($callback, $arguments, $noneValue) {
/** @var mixed */
$return = call_user_func_array($callback, $arguments);

if ($return === $noneValue) {
Expand Down Expand Up @@ -126,6 +127,7 @@ public static function ensure($value, $noneValue = null)
return $value;
} elseif (is_callable($value)) {
return new LazyOption(function () use ($value, $noneValue) {
/** @var mixed */
$return = $value();

if ($return instanceof self) {
Expand Down Expand Up @@ -158,20 +160,32 @@ public static function ensure($value, $noneValue = null)
public static function lift($callback, $noneValue = null)
{
return function () use ($callback, $noneValue) {
/** @var array<int, mixed> */
$args = func_get_args();

$reduced_args = array_reduce(
$args,
/** @param bool $status */
function ($status, self $o) {
return $o->isEmpty() ? true : $status;
},
false
);
// if at least one parameter is empty, return None
if (array_reduce($args, function ($status, self $o) {
return $o->isEmpty() ? true : $status;
}, false)) {
if ($reduced_args) {
return None::create();
}

$args = array_map(function (self $o) {
// it is safe to do so because the fold above checked
// that all arguments are of type Some
return $o->get();
}, $args);
$args = array_map(
/** @return T */
function (self $o) {
// it is safe to do so because the fold above checked
// that all arguments are of type Some
/** @var T */
return $o->get();
},
$args
);

return self::ensure(call_user_func_array($callback, $args), $noneValue);
};
Expand Down Expand Up @@ -205,7 +219,7 @@ abstract public function getOrElse($default);
*
* @template S
*
* @param callable(): S $callable
* @param callable():S $callable
*
* @return T|S
*/
Expand Down Expand Up @@ -270,7 +284,7 @@ abstract public function orElse(self $else);
*
* @deprecated Use forAll() instead.
*
* @param callable $callable
* @param callable(T):mixed $callable
*
* @return void
*/
Expand All @@ -283,7 +297,7 @@ abstract public function ifDefined($callable);
* option is empty. This method is preferred for callables with side-effects, while map()
* is intended for callables without side-effects.
*
* @param callable(T): void $callable
* @param callable(T):mixed $callable
*
* @return Option<T>
*/
Expand All @@ -301,7 +315,7 @@ abstract public function forAll($callable);
*
* @template S
*
* @param callable(T): S $callable
* @param callable(T):S $callable
*
* @return Option<S>
*/
Expand All @@ -316,7 +330,7 @@ abstract public function map($callable);
*
* @template S
*
* @param callable(T): Option<S> $callable must return an Option
* @param callable(T):Option<S> $callable must return an Option
*
* @return Option<S>
*/
Expand All @@ -328,7 +342,7 @@ abstract public function flatMap($callable);
* If the option is non-empty, the callable is applied, and if it returns true,
* the option itself is returned; otherwise, None is returned.
*
* @param callable(T): bool $callable
* @param callable(T):bool $callable
*
* @return Option<T>
*/
Expand Down Expand Up @@ -399,8 +413,8 @@ abstract public function reject($value);
*
* @template S
*
* @param S $initialValue
* @param callable $callable function(initialValue, callable): result
* @param S $initialValue
* @param callable(S, T):S $callable
*
* @return S
*/
Expand All @@ -411,8 +425,8 @@ abstract public function foldLeft($initialValue, $callable);
*
* @template S
*
* @param S $initialValue
* @param callable $callable function(callable, initialValue): result
* @param S $initialValue
* @param callable(T, S):S $callable
*
* @return S
*/
Expand Down
6 changes: 4 additions & 2 deletions src/PhpOption/Some.php
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,11 @@ public function __construct($value)
}

/**
* @param T $value
* @template U
*
* @param U $value
*
* @return Some<T>
* @return Some<U>
*/
public static function create($value)
{
Expand Down

0 comments on commit ea10a97

Please sign in to comment.