public function juggle(Type $type) { if (array_filter($this->types, function (Type $element) use($type) { return array_filter($type->getTypes(), function (Type $element) use($type) { return $element->juggle($type); }); })) { return $type; } return null; }
public function juggle(Type $type) { /* * This is a predicate to determine whether the CURRENT type (the child class) * can be juggled into the Type $type. */ $predicate = function (Type $element) { return array_any($this->getAllowedJuggleTypes(), function (Type $value, $index, $collection) use($element) { return (bool) Type::intersect($element, $value); }); }; $x = array_filter($type->getTypes(), $predicate); if (!$x) { return null; } if (count($x) === 1) { return first($x); } return UnionType::createIfNotDuplicate(array_shift($x), ...$x); }
/** * Flatten Types, e.g. flatten UnionTypes. * * This function won't have much of an effect on most types, unless they contain subtypes. * * Because this function preserves duplicate entries, usually it may be preferable to use Type::unique() * which also flattens and removes duplicate entries. * * @param Type|Type[] ...$types Use array dereferencing to pass an array into this function. * * @return array */ public static function flatten(Type ...$types) { // Flatten types with subtypes e.g. UnionTypes $walker = function (Type $x) { // If the types $x contains is not just itself, go deeper! if (count($x->getTypes()) !== 1 or !first($x->getTypes())->typeof($x)) { return Type::flatten($x); } return $x->getTypes(); }; $x = array_map($walker, $types); return array_flatten($x); }