Skip to content

Commit 6be63bc

Browse files
committed
feat: Add Blackbird combinator.
1 parent 62d213d commit 6be63bc

5 files changed

Lines changed: 114 additions & 0 deletions

File tree

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace spec\loophp\combinator\Combinator;
6+
7+
use Closure;
8+
use PhpSpec\ObjectBehavior;
9+
10+
class BlackbirdSpec extends ObjectBehavior
11+
{
12+
public function it_is_initializable()
13+
{
14+
$a = 'array_sum';
15+
16+
$b = static fn (callable $c): Closure => static fn (array $v): array => array_map($c, $v);
17+
18+
$c = 'count';
19+
20+
$this::of()($a)($b)($c)([['a', 'b', 'c'], ['a', 'b']])
21+
->shouldReturn(5);
22+
}
23+
}

spec/loophp/combinator/CombinatorsSpec.php

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,43 @@ public function it_can_test_the_B_combinator()
7474
);
7575
}
7676

77+
public function it_can_test_the_Blackbird_combinator()
78+
{
79+
$a = 'array_sum';
80+
81+
$b = static fn (callable $c): Closure => static fn (array $v): array => array_map($c, $v);
82+
83+
$c = 'count';
84+
85+
$d = [['a', 'b', 'c'], ['a', 'b']];
86+
87+
$this::Blackbird()($a)($b)($c)($d)
88+
->shouldReturn(5);
89+
90+
// (S(K(S(KS)K)))(S(KS)K)
91+
$this::Blackbird()($a)($b)($c)($d)
92+
->shouldReturn(
93+
Combinators::S()(
94+
Combinators::K()
95+
(
96+
Combinators::S()
97+
(
98+
Combinators::K()(Combinators::S())
99+
)
100+
(Combinators::K())
101+
)
102+
)
103+
(
104+
Combinators::S()
105+
(
106+
Combinators::K()(Combinators::S())
107+
)
108+
(Combinators::K())
109+
)
110+
($a)($b)($c)($d)
111+
);
112+
}
113+
77114
public function it_can_test_the_C_combinator()
78115
{
79116
$f = static function ($x) {

src/Combinator/Blackbird.php

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace loophp\combinator\Combinator;
6+
7+
use Closure;
8+
use loophp\combinator\Combinator;
9+
10+
/**
11+
* Class Blackbird.
12+
*
13+
* @template NewAType
14+
* @template NewBType
15+
* @template NewCType
16+
* @template NewDType
17+
*
18+
* phpcs:disable Generic.Files.LineLength.TooLong
19+
*/
20+
final class Blackbird extends Combinator
21+
{
22+
/**
23+
* @return Closure(callable(NewCType): NewDType): Closure(callable(NewAType): callable(NewBType): NewCType): Closure(NewAType): Closure(NewBType): NewCType
24+
*/
25+
public function __invoke(): Closure
26+
{
27+
return B::of()(B::of())(B::of());
28+
}
29+
}

src/Combinators.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
use Closure;
88
use loophp\combinator\Combinator\A;
99
use loophp\combinator\Combinator\B;
10+
use loophp\combinator\Combinator\Blackbird;
1011
use loophp\combinator\Combinator\C;
1112
use loophp\combinator\Combinator\D;
1213
use loophp\combinator\Combinator\E;
@@ -52,6 +53,11 @@ public static function B(): Closure
5253
return B::of();
5354
}
5455

56+
public static function Blackbird(): Closure
57+
{
58+
return Blackbird::of();
59+
}
60+
5561
public static function C(): Closure
5662
{
5763
return C::of();
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace loophp\combinator\Tests\StaticAnalysis;
6+
7+
use loophp\combinator\Combinator\Blackbird;
8+
9+
/**
10+
* @param Blackbird<int, int, int, int> $combinator
11+
* @param callable(int): int $f
12+
* @param callable(string): Closure(string): int $g
13+
* @param string $h
14+
* @param string $x
15+
*/
16+
function test(Blackbird $combinator, callable $f, callable $g, int $h, int $x): int
17+
{
18+
return $combinator->__invoke()($f)($g)($h)($x);
19+
}

0 commit comments

Comments
 (0)