1 | <?php |
||||
2 | declare(strict_types = 1); |
||||
3 | |||||
4 | namespace Innmind\Immutable\Sequence; |
||||
5 | |||||
6 | use Innmind\Immutable\{ |
||||
7 | Map, |
||||
8 | Sequence, |
||||
9 | Str, |
||||
10 | Set, |
||||
11 | Maybe, |
||||
12 | SideEffect, |
||||
13 | }; |
||||
14 | |||||
15 | /** |
||||
16 | * @template T |
||||
17 | * @psalm-immutable |
||||
18 | */ |
||||
19 | final class Primitive implements Implementation |
||||
20 | { |
||||
21 | /** @var list<T> */ |
||||
0 ignored issues
–
show
|
|||||
22 | private array $values; |
||||
23 | |||||
24 | /** |
||||
25 | * @param list<T> $values |
||||
26 | */ |
||||
27 | public function __construct(array $values = []) |
||||
28 | { |
||||
29 | $this->values = $values; |
||||
0 ignored issues
–
show
It seems like
$values of type array is incompatible with the declared type Innmind\Immutable\Sequence\list of property $values .
Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property. Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property.. ![]() |
|||||
30 | } |
||||
31 | |||||
32 | /** |
||||
33 | 279 | * @param T $element |
|||
0 ignored issues
–
show
The type
Innmind\Immutable\Sequence\T was not found. Maybe you did not declare it correctly or list all dependencies?
The issue could also be caused by a filter entry in the build configuration.
If the path has been excluded in your configuration, e.g. filter:
dependency_paths: ["lib/*"]
For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths ![]() |
|||||
34 | * |
||||
35 | 279 | * @return self<T> |
|||
36 | 279 | */ |
|||
37 | 279 | public function __invoke($element): self |
|||
38 | 279 | { |
|||
39 | 279 | $values = $this->values; |
|||
0 ignored issues
–
show
It seems like
$this->values of type array is incompatible with the declared type Innmind\Immutable\Sequence\list of property $values .
Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property. Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property.. ![]() |
|||||
40 | $values[] = $element; |
||||
41 | 3 | ||||
42 | return new self($values); |
||||
43 | 3 | } |
|||
44 | |||||
45 | public function size(): int |
||||
46 | 177 | { |
|||
47 | return \count($this->values); |
||||
48 | 177 | } |
|||
49 | |||||
50 | public function count(): int |
||||
51 | 8 | { |
|||
52 | return $this->size(); |
||||
53 | 8 | } |
|||
54 | |||||
55 | /** |
||||
56 | * @return \Iterator<int, T> |
||||
57 | */ |
||||
58 | public function iterator(): \Iterator |
||||
59 | 74 | { |
|||
60 | return new \ArrayIterator($this->values); |
||||
61 | 74 | } |
|||
62 | |||||
63 | /** |
||||
64 | * @return Maybe<T> |
||||
65 | */ |
||||
66 | public function get(int $index): Maybe |
||||
67 | { |
||||
68 | if (!$this->has($index)) { |
||||
69 | 37 | /** @var Maybe<T> */ |
|||
70 | return Maybe::nothing(); |
||||
71 | 37 | } |
|||
72 | 4 | ||||
73 | return Maybe::just($this->values[$index]); |
||||
74 | } |
||||
75 | 33 | ||||
76 | /** |
||||
77 | * @param Implementation<T> $sequence |
||||
78 | * |
||||
79 | * @return self<T> |
||||
80 | */ |
||||
81 | public function diff(Implementation $sequence): self |
||||
82 | { |
||||
83 | 4 | return $this->filter(static function(mixed $value) use ($sequence): bool { |
|||
84 | /** @var T $value */ |
||||
85 | return !$sequence->contains($value); |
||||
86 | }); |
||||
87 | 4 | } |
|||
88 | 4 | ||||
89 | /** |
||||
90 | * @return self<T> |
||||
91 | */ |
||||
92 | public function distinct(): self |
||||
93 | { |
||||
94 | 99 | return $this->reduce( |
|||
95 | $this->clear(), |
||||
96 | 99 | static function(self $values, mixed $value): self { |
|||
97 | 99 | /** @var T $value */ |
|||
98 | if ($values->contains($value)) { |
||||
99 | 52 | return $values; |
|||
100 | 8 | } |
|||
101 | |||||
102 | return ($values)($value); |
||||
103 | 52 | }, |
|||
104 | 99 | ); |
|||
105 | } |
||||
106 | |||||
107 | /** |
||||
108 | * @return self<T> |
||||
109 | */ |
||||
110 | public function drop(int $size): self |
||||
111 | 5 | { |
|||
112 | return new self(\array_slice($this->values, $size)); |
||||
113 | 5 | } |
|||
114 | 5 | ||||
115 | /** |
||||
116 | 5 | * @return self<T> |
|||
117 | */ |
||||
118 | public function dropEnd(int $size): self |
||||
119 | { |
||||
120 | return new self(\array_slice($this->values, 0, $this->size() - $size)); |
||||
121 | } |
||||
122 | 3 | ||||
123 | /** |
||||
124 | 3 | * @param Implementation<T> $sequence |
|||
125 | 3 | */ |
|||
126 | public function equals(Implementation $sequence): bool |
||||
127 | 3 | { |
|||
128 | /** @psalm-suppress ImpureFunctionCall */ |
||||
129 | return $this->values === \iterator_to_array($sequence->iterator()); |
||||
130 | } |
||||
131 | |||||
132 | /** |
||||
133 | 8 | * @param callable(T): bool $predicate |
|||
134 | * |
||||
135 | 8 | * @return self<T> |
|||
136 | */ |
||||
137 | public function filter(callable $predicate): self |
||||
138 | { |
||||
139 | /** @psalm-suppress ImpureFunctionCall */ |
||||
140 | return new self(\array_values(\array_filter( |
||||
141 | $this->values, |
||||
142 | $predicate, |
||||
143 | 22 | ))); |
|||
144 | } |
||||
145 | 22 | ||||
146 | 22 | /** |
|||
147 | 22 | * @param callable(T): void $function |
|||
148 | 22 | */ |
|||
149 | public function foreach(callable $function): SideEffect |
||||
150 | { |
||||
151 | 22 | foreach ($this->values as $value) { |
|||
152 | $function($value); |
||||
153 | } |
||||
154 | |||||
155 | return new SideEffect; |
||||
156 | } |
||||
157 | 4 | ||||
158 | /** |
||||
159 | 4 | * @template D |
|||
160 | 4 | * @param callable(T): D $discriminator |
|||
161 | * |
||||
162 | 4 | * @return Map<D, Sequence<T>> |
|||
163 | */ |
||||
164 | public function groupBy(callable $discriminator): Map |
||||
165 | { |
||||
166 | /** @var Map<D, Sequence<T>> */ |
||||
167 | $groups = Map::of(); |
||||
168 | |||||
169 | foreach ($this->values as $value) { |
||||
170 | $key = $discriminator($value); |
||||
171 | |||||
172 | 9 | /** @var Sequence<T> */ |
|||
173 | $group = $groups->get($key)->match( |
||||
174 | 9 | static fn($group) => $group, |
|||
175 | 3 | static fn() => Sequence::of(), |
|||
176 | ); |
||||
177 | $groups = ($groups)($key, ($group)($value)); |
||||
178 | 6 | } |
|||
179 | |||||
180 | 6 | /** @var Map<D, Sequence<T>> */ |
|||
181 | 6 | return $groups; |
|||
182 | } |
||||
183 | 6 | ||||
184 | /** |
||||
185 | 6 | * @return Maybe<T> |
|||
186 | 6 | */ |
|||
187 | 6 | public function first(): Maybe |
|||
188 | { |
||||
189 | return $this->get(0); |
||||
190 | } |
||||
191 | 6 | ||||
192 | /** |
||||
193 | 6 | * @return Maybe<T> |
|||
194 | */ |
||||
195 | 6 | public function last(): Maybe |
|||
196 | { |
||||
197 | 6 | return $this->get($this->size() - 1); |
|||
198 | } |
||||
199 | 6 | ||||
200 | /** |
||||
201 | * @param T $element |
||||
202 | */ |
||||
203 | public function contains($element): bool |
||||
204 | 6 | { |
|||
205 | return \in_array($element, $this->values, true); |
||||
206 | } |
||||
207 | |||||
208 | /** |
||||
209 | * @param T $element |
||||
210 | 6 | * |
|||
211 | * @return Maybe<int> |
||||
212 | 6 | */ |
|||
213 | public function indexOf($element): Maybe |
||||
214 | { |
||||
215 | $index = \array_search($element, $this->values, true); |
||||
216 | |||||
217 | if ($index === false) { |
||||
218 | 6 | /** @var Maybe<int> */ |
|||
219 | return Maybe::nothing(); |
||||
220 | 6 | } |
|||
221 | |||||
222 | return Maybe::just($index); |
||||
0 ignored issues
–
show
$index of type integer|string is incompatible with the type Innmind\Immutable\V expected by parameter $value of Innmind\Immutable\Maybe::just() .
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||
223 | } |
||||
224 | |||||
225 | /** |
||||
226 | 113 | * @psalm-suppress LessSpecificImplementedReturnType Don't why it complains |
|||
227 | * |
||||
228 | 113 | * @return self<int> |
|||
229 | */ |
||||
230 | public function indices(): self |
||||
231 | { |
||||
232 | if ($this->empty()) { |
||||
233 | /** @var self<int> */ |
||||
234 | return new self; |
||||
235 | } |
||||
236 | 23 | ||||
237 | /** @var self<int> */ |
||||
238 | 23 | return new self(\range(0, $this->size() - 1)); |
|||
239 | } |
||||
240 | 23 | ||||
241 | 1 | /** |
|||
242 | * @template S |
||||
243 | * |
||||
244 | 22 | * @param callable(T): S $function |
|||
245 | * |
||||
246 | * @return self<S> |
||||
247 | */ |
||||
248 | public function map(callable $function): self |
||||
249 | { |
||||
250 | /** @psalm-suppress ImpureFunctionCall */ |
||||
251 | return new self(\array_map($function, $this->values)); |
||||
252 | 4 | } |
|||
253 | |||||
254 | 4 | /** |
|||
255 | * @template S |
||||
256 | 2 | * |
|||
257 | * @param callable(T): Sequence<S> $map |
||||
258 | * @param callable(Sequence<S>): Implementation<S> $exfiltrate |
||||
259 | * |
||||
260 | 2 | * @return Sequence<S> |
|||
261 | */ |
||||
262 | public function flatMap(callable $map, callable $exfiltrate): Sequence |
||||
263 | { |
||||
264 | /** |
||||
265 | * @psalm-suppress MixedArgument |
||||
266 | * @var Sequence<S> |
||||
267 | */ |
||||
268 | 5 | return $this->reduce( |
|||
269 | Sequence::of(), |
||||
270 | static fn(Sequence $carry, $value) => $carry->append($map($value)), |
||||
271 | ); |
||||
272 | } |
||||
273 | |||||
274 | /** |
||||
275 | * @param T $element |
||||
276 | 5 | * |
|||
277 | 5 | * @return self<T> |
|||
278 | */ |
||||
279 | 3 | public function pad(int $size, $element): self |
|||
280 | 5 | { |
|||
281 | return new self(\array_pad($this->values, $size, $element)); |
||||
282 | 5 | } |
|||
283 | 5 | ||||
284 | /** |
||||
285 | 3 | * @param callable(T): bool $predicate |
|||
286 | * |
||||
287 | * @return Map<bool, Sequence<T>> |
||||
288 | */ |
||||
289 | public function partition(callable $predicate): Map |
||||
290 | { |
||||
291 | /** @var list<T> */ |
||||
292 | $truthy = []; |
||||
293 | 2 | /** @var list<T> */ |
|||
294 | $falsy = []; |
||||
295 | 2 | ||||
296 | 2 | foreach ($this->values as $value) { |
|||
297 | if ($predicate($value) === true) { |
||||
298 | 2 | $truthy[] = $value; |
|||
299 | } else { |
||||
300 | $falsy[] = $value; |
||||
301 | } |
||||
302 | } |
||||
303 | |||||
304 | $true = Sequence::of(...$truthy); |
||||
305 | $false = Sequence::of(...$falsy); |
||||
306 | 6 | ||||
307 | return Map::of([true, $true], [false, $false]); |
||||
308 | } |
||||
309 | 6 | ||||
310 | /** |
||||
311 | 6 | * @return self<T> |
|||
312 | */ |
||||
313 | 6 | public function slice(int $from, int $until): self |
|||
314 | 6 | { |
|||
315 | 6 | return new self(\array_slice( |
|||
316 | $this->values, |
||||
317 | 6 | $from, |
|||
318 | $until - $from, |
||||
319 | )); |
||||
320 | } |
||||
321 | |||||
322 | 6 | /** |
|||
323 | * @return self<T> |
||||
324 | 6 | */ |
|||
325 | public function take(int $size): self |
||||
326 | { |
||||
327 | return $this->slice(0, $size); |
||||
328 | } |
||||
329 | |||||
330 | 6 | /** |
|||
331 | 6 | * @return self<T> |
|||
332 | 6 | */ |
|||
333 | public function takeEnd(int $size): self |
||||
334 | { |
||||
335 | return $this->slice($this->size() - $size, $this->size()); |
||||
336 | } |
||||
337 | |||||
338 | 16 | /** |
|||
339 | * @param Implementation<T> $sequence |
||||
340 | 16 | * |
|||
341 | 16 | * @return self<T> |
|||
342 | 16 | */ |
|||
343 | 16 | public function append(Implementation $sequence): self |
|||
344 | 16 | { |
|||
345 | /** @psalm-suppress ImpureFunctionCall */ |
||||
346 | return new self(\array_merge( |
||||
347 | 16 | $this->values, |
|||
348 | \iterator_to_array($sequence->iterator()), |
||||
349 | )); |
||||
350 | } |
||||
351 | |||||
352 | /** |
||||
353 | * @param Implementation<T> $sequence |
||||
354 | * |
||||
355 | 3 | * @return self<T> |
|||
356 | */ |
||||
357 | public function intersect(Implementation $sequence): self |
||||
358 | 3 | { |
|||
359 | return $this->filter(static function(mixed $value) use ($sequence): bool { |
||||
360 | 3 | /** @var T $value */ |
|||
361 | return $sequence->contains($value); |
||||
362 | }); |
||||
363 | 3 | } |
|||
364 | |||||
365 | /** |
||||
366 | * @param callable(T, T): int $function |
||||
367 | * |
||||
368 | * @return self<T> |
||||
369 | 5 | */ |
|||
370 | public function sort(callable $function): self |
||||
371 | 5 | { |
|||
372 | $self = clone $this; |
||||
373 | /** @psalm-suppress ImpureFunctionCall */ |
||||
374 | \usort($self->values, $function); |
||||
375 | |||||
376 | return $self; |
||||
377 | 3 | } |
|||
378 | |||||
379 | 3 | /** |
|||
380 | * @template R |
||||
381 | * @param R $carry |
||||
0 ignored issues
–
show
The type
Innmind\Immutable\Sequence\R was not found. Maybe you did not declare it correctly or list all dependencies?
The issue could also be caused by a filter entry in the build configuration.
If the path has been excluded in your configuration, e.g. filter:
dependency_paths: ["lib/*"]
For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths ![]() |
|||||
382 | * @param callable(R, T): R $reducer |
||||
383 | * |
||||
384 | * @return R |
||||
385 | */ |
||||
386 | public function reduce($carry, callable $reducer) |
||||
387 | 8 | { |
|||
388 | /** |
||||
389 | 8 | * @psalm-suppress ImpureFunctionCall |
|||
390 | * @var R |
||||
391 | 8 | */ |
|||
392 | return \array_reduce($this->values, $reducer, $carry); |
||||
393 | 8 | } |
|||
394 | |||||
395 | /** |
||||
396 | * @return self<T> |
||||
397 | */ |
||||
398 | public function clear(): Implementation |
||||
399 | { |
||||
400 | return new self; |
||||
401 | 14 | } |
|||
402 | |||||
403 | /** |
||||
404 | * @return self<T> |
||||
405 | 14 | */ |
|||
406 | 14 | public function reverse(): self |
|||
407 | { |
||||
408 | return new self(\array_reverse($this->values)); |
||||
409 | } |
||||
410 | |||||
411 | public function empty(): bool |
||||
412 | { |
||||
413 | return !$this->has(0); |
||||
414 | 163 | } |
|||
415 | |||||
416 | 163 | /** |
|||
417 | 163 | * @return Sequence<T> |
|||
418 | 163 | */ |
|||
419 | public function toSequence(): Sequence |
||||
420 | 163 | { |
|||
421 | return Sequence::of(...$this->values); |
||||
422 | } |
||||
423 | |||||
424 | /** |
||||
425 | * @return Set<T> |
||||
426 | */ |
||||
427 | public function toSet(): Set |
||||
428 | 4 | { |
|||
429 | return Set::of(...$this->values); |
||||
430 | 4 | } |
|||
431 | 4 | ||||
432 | public function find(callable $predicate): Maybe |
||||
433 | 4 | { |
|||
434 | foreach ($this->values as $value) { |
||||
435 | if ($predicate($value) === true) { |
||||
436 | return Maybe::just($value); |
||||
437 | } |
||||
438 | } |
||||
439 | |||||
440 | /** @var Maybe<T> */ |
||||
441 | return Maybe::nothing(); |
||||
442 | } |
||||
443 | 185 | ||||
444 | public function match(callable $wrap, callable $match, callable $empty) |
||||
445 | { |
||||
446 | 185 | return $this |
|||
447 | ->first() |
||||
448 | ->match( |
||||
449 | fn($first) => $match($first, $wrap($this->drop(1))), |
||||
450 | $empty, |
||||
451 | ); |
||||
452 | 130 | } |
|||
453 | |||||
454 | 130 | private function has(int $index): bool |
|||
455 | { |
||||
456 | return \array_key_exists($index, $this->values); |
||||
457 | } |
||||
458 | } |
||||
459 |
The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g.
excluded_paths: ["lib/*"]
, you can move it to the dependency path list as follows:For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths