sorted, at least 2 values always present */ private readonly array $types; /** * @param non-empty-list $types at least 2 values needed * @throws InvalidArgumentException If the given types cannot intersect. */ public function __construct(array $types) { usort( $types, static fn(AtomicType $a, AtomicType $b): int => $a->type <=> $b->type ); foreach ($types as $index => $atomicType) { foreach (array_diff_key($types, array_flip([$index])) as $otherType) { $atomicType->assertCanIntersectWith($otherType); } } $this->types = $types; } /** @return non-empty-string */ public function toString(): string { return implode( '&', array_map(static fn(AtomicType $type): string => $type->toString(), $this->types) ); } /** @return non-empty-string */ public function fullyQualifiedName(): string { return implode( '&', array_map(static fn(AtomicType $type): string => $type->fullyQualifiedName(), $this->types) ); } /** @throws InvalidArgumentException When the union is not possible. */ public function assertCanUnionWith(AtomicType|self $other): void { if ($other instanceof AtomicType) { foreach ($this->types as $type) { $type->assertCanUnionWith($other); } return; } $thisString = $this->toString(); $otherString = $other->toString(); if (str_contains($thisString, $otherString) || str_contains($otherString, $thisString)) { throw new InvalidArgumentException(sprintf( 'Types "%s" and "%s" cannot be intersected, as they include each other', $thisString, $otherString )); } } } __halt_compiler();----SIGNATURE:----KSyO8jul/UxPI8EYEzj5cVD98BgqOdqZJE+quRBihby4yav7BL9Iz+PAf6NYmn7ryNHu8maiHblFjevHofNrIIeYLoGodaioyLVl0sEFZhn7vSm4yOuaGiDez5X/VP/Cggp/k6yEIrWlFvqKtZUwvkA+DsQfBBVVQT88So29JJHQHqDLl6kueieShXrQWWAZ/kCdiGbx69RGYSWNGWU6VG+pddn+5a1742VcdZW18nz0Sc4+xfznwgBz+MiqsKzK+zyTFSNl1oph1QHNjEmHVZ+SDeUdmKzQEa0fnCbu8O447QPP2TpGdTRT6QR2aQUC2L+3VjTi49QQ5ngYWubkMDo1WxUqwxtYEwEkw2lx0CpJmBMZymdCuEp+rZ8u9+ACoXfC5DZMAMrkebke5Zj++XBeMyrjzcaEvgEqpieGElCMtygUCaUJT4Yo1o9wZB7vSJWZr5y+XnAZSClU1ClwOqFXk0z4wiAd2oSBM3VDgv58netg2UvViSpF6NDS/811Lby7oD8J1KLO9phc88jI2h95paqOZisM7L+YbS6OxQWMdGypRf8Oo5WjGPOgaUOHCqQ9LlW1oBZJBFPTYWGeQZUcshvBZby1PWFSDOpKGYD/ydVhZhQOyNiRiYvDUszRzUBlbusrS1qy1YP3z9JmBnk5ckvYIVHc0bBDJlirs6M=----ATTACHMENT:----NDc2MTEzMDc2MTY3MTQ0OCAyNzQxMDA1NjA0NTE0NTEgNDc1OTIyNTg0NjcyMjI2