*
* unzip transforms a list of pairs into a list of first components and a list of second components.
*
- * @param Listt $a
+ * @param Listt $xs
* @return array
*/
-function unzip(Listt $a): array
+function unzip(Listt $xs): array
{
- return foldr(function ($ab, $abs) {
- [$a, $b] = $ab;
- [$as, $bs] = $abs;
+ try {
+ [$x, $y] = head($xs);
return [
- prepend($a, $as),
- prepend($b, $bs)
+ ListtCons::of(function () use ($x, $xs) {
+ return [$x, unzip(tail($xs))[0]];
+ }),
+ ListtCons::of(function () use ($y, $xs) {
+ return [$y, unzip(tail($xs))[1]];
+ }),
];
- }, [fromNil(), fromNil()], $a);
+ } catch (EmptyListError $e) {
+ return [fromNil(), fromNil()];
+ }
}
namespace test\Functional;
-use function Widmogrod\Functional\fromNil;
+use Eris\Generator;
+use Eris\TestTrait;
use Widmogrod\Primitive\Listt;
+use function Widmogrod\Functional\eql;
+use function Widmogrod\Functional\filter;
use function Widmogrod\Functional\fromIterable;
+use function Widmogrod\Functional\fromNil;
+use function Widmogrod\Functional\length;
+use function Widmogrod\Functional\repeat;
+use function Widmogrod\Functional\take;
use function Widmogrod\Functional\unzip;
class UnzipTest extends \PHPUnit_Framework_TestCase
{
+ use TestTrait;
+
/**
* @dataProvider provideData
*/
],
];
}
+
+ public function test_it_should_work_on_infinite_lists()
+ {
+ $this->forAll(
+ Generator\choose(1, 100),
+ Generator\string(),
+ Generator\string()
+ )->then(function ($n, $x, $y) {
+ [$xs, $ys] = unzip(repeat([$x, $y]));
+
+ return length(filter(eql($x), take($n, $xs))) === $n
+ && length(filter(eql($y), take($n, $ys))) === $n;
+ });
+ }
}