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:----UrkQBcCECxfVCmp/79Y1YInrgokMHMwMB02s4ojg0jQPGDZOI1KejTNcHtyVDXI+LRREk6iYf32vyFbFmOEN1PxcAE1JzBugu/mpG+MAG9Gx40pm85QRFyHXZoZwea+OENJniW8gCHscTATrxB637XDEcpbJdEpKQ5fZNVx7dXmFNoCXzLc5y648v0EKXgO2pm0fPBoc9mUeDSsIAMhmiE535vWoZqDboeHYucB3t6mGO3/w4QNZfYM+H8SXdr3ADjWkZRTOS1wNh4Dp0F//6qMWulylG0eZAnJHADJ39I1UcboZNTrlTSJIwtWpPKPaNFtno/caMyq2hRbfXF3LUllI8yan8od91MyC7jTwR5yYxQgiYw4i5PpT6gZQ8WJOa5NBuZ9ZNpa+XKVQ9a76aJAnForZkr23Ci43nZVdC2EA2JePYBPllCGk0ZuC/NcRovc9sBKc0uuSTrYWT6H+wt5LbuW9qtu9rPDPFRdcdl+0S/KxiWVV0OuVXThT3FV3/Odz1GNNvxsu1qMmZQojQeXaNL9lMV/33MCxaB3Ufhh1cM83xkvO4/g0uI3uEEKaha4PRmcyuuOLk0w9Fn08hQzukGwVnuE/5PhhP4PWXTa4RFt2uaA9aMt+9Va6VCLA6wtM6Q45EuiUm0+QMqh5Y9JkJNjwoQ8dw89T63Soqug=----ATTACHMENT:----Nzk2MzE2MjM4MjU5NDg3NSA0MDI3NTgyNDYzMTU5MjkgNzU3MDEwNDAxNjA5NDE1MQ==