11# Combinators
22** Contents**
3- - [ \* N combinators] ( #\* N-combinators )
3+ - [ N combinators] ( #N-combinators )
44 - [ Introduction] ( #Introduction )
55 - [ Omit values from tuple or shape] ( #Omit-values-from-tuple-or-shape )
66 - [ Ctor function] ( #Ctor-function )
77 - [ Caveats] ( #Caveats )
8- - [ \* KV combinators] ( #\* KV-combinators )
8+ - [ KV combinators] ( #KV-combinators )
99 - [ Map] ( #Map )
1010 - [ Functions] ( #Functions )
11+ - [ T combinators] ( #T-combinators )
1112
12- # \* N combinators
13+ # N combinators
1314
1415 - #### Introduction
1516
@@ -38,7 +39,8 @@ use function Fp\Collection\sequenceOptionT;
3839use function Fp\Evidence\proveArray;
3940use function Fp\Evidence\proveBool;
4041use function Fp\Evidence\proveInt;
41- use function Fp\Json\jsonDecode;
42+ use function Fp\Util\jsonDecode;
43+ use function Fp\Callable\ctor;
4244
4345$json = <<<JSON
4446{
@@ -60,7 +62,10 @@ function fooFromJson(string $json): Option
6062 fn() => at($data, 'b')->flatMap(proveBool(...)),
6163 fn() => at($data, 'c')->flatMap(proveBool(...)),
6264 ))
63- ->mapN(fn(int $a, bool $b, bool $c) => new Foo($a, $b, $c));
65+ ->mapN(ctor(Foo::class));
66+
67+ // or more verbose version:
68+ // ->mapN(fn(int $a, bool $b, bool $c) => new Foo($a, $b, $c));
6469}
6570```
6671
@@ -128,7 +133,7 @@ three parameters. This is non-valid case and Psalm tells about it.
128133
129134 - #### Ctor function
130135
131- There is useful function ` Fp\Callable\ctor ` that is friend of \* N
136+ There is useful function ` Fp\Callable\ctor ` that is friend of N
132137combinators. Examples above can be rewritten as follows:
133138
134139``` php
@@ -158,8 +163,8 @@ unnecessary args, psalm issues)
158163
159164 - #### Caveats
160165
161- For shapes with string keys the ` Fp\Callable\ctor ` and \* N combinators
162- use ` ReflectionFunction ` but for tuples not.
166+ For shapes with string keys the ` Fp\Callable\ctor ` and N combinators use
167+ ` ReflectionFunction ` but for tuples not.
163168
164169For tuples reflection is unnecessary because PHP allows to pass extra
165170arguments to functions with array spread:
@@ -205,15 +210,15 @@ test(...['a' => 1, 'b' => 2, 'c' => 3, 'd' => 4]);
205210So ` ReflectionFunction ` used for filtering extra arguments before array
206211will be spread.
207212
208- # \* KV combinators
213+ # KV combinators
209214
210215 - #### Map
211216
212217Before v5 ` Fp\Collections\Map ` used ` Fp\Collections\Entry ` to represents
213218kv pair. It was unfriendly for ide (lack autocompletion ability).
214219
215220Since v5 ` Fp\Collections\Entry ` has been removed. Instead, each method
216- of ` Fp\Collections\Map ` has \* KV version:
221+ of ` Fp\Collections\Map ` has KV version:
217222
218223``` php
219224<?php
@@ -244,7 +249,7 @@ time.
244249
245250 - #### Functions
246251
247- Regular functions has \* KV combinators too:
252+ Regular functions has KV combinators too:
248253
249254``` php
250255<?php
@@ -272,3 +277,60 @@ function sumWithKeys(array $hashMap): HashMap
272277 return mapKV($hashMap, fn(int $key, int $value) => $key + $value);
273278}
274279```
280+
281+ Keys were passed as the second parameter $callback/$predicate prior to
282+ v5. At first glance, it was convenient. This leads to such problems:
283+ < https://psalm.dev/r/f00c0b19be > . But with v5 there is no problem
284+ anymore: < https://psalm.dev/r/20e91dfded > .
285+
286+ # T combinators
287+
288+ That combinators accepts varargs as input and return tuples.
289+
290+ ` Fp\Collection\partitionT ` :
291+
292+ ``` php
293+ <?php
294+
295+ use Tests\Mock\Foo;
296+ use Tests\Mock\Bar;
297+ use Tests\Mock\Baz;
298+
299+ use function Fp\Collection\partitionT;
300+
301+ /**
302+ * @param list<Foo |Bar|Baz > $list
303+ * @return array{list<Foo >, list<Bar >, list<Baz >}
304+ */
305+ function example(array $list): array
306+ {
307+ return partitionT($list, fn($i) => $i instanceof Foo, fn($i) => $i instanceof Bar);
308+ }
309+ ```
310+
311+ ` Fp\Collection\sequenceOptionT ` :
312+
313+ ``` php
314+ <?php
315+
316+ use Fp\Functional\Option\Option;
317+
318+ use function Fp\Evidence\proveInt;
319+ use function Fp\Evidence\proveString;
320+ use function Fp\Collection\sequenceOptionT;
321+ use function Fp\Collection\at;
322+
323+ /**
324+ * @param array<string , mixed > $data
325+ * @return Option<array {string, int} >
326+ */
327+ function sequenceT(array $data): Option
328+ {
329+ return sequenceOptionT(
330+ at($data, 'name')->flatMap(proveString(...)),
331+ at($data, 'age')->flatMap(proveInt(...)),
332+ );
333+ }
334+ ```
335+
336+ And others.
0 commit comments