function prepend($x, Listt $xs = null)
{
return curryN(2, function ($x, Listt $xs): Listt {
- return append(fromValue($x), $xs);
+ return ListtCons::of(function () use ($x, $xs) {
+ return [$x, $xs];
+ });
})(...func_get_args());
}
use Widmogrod\Primitive\EmptyListError;
use Widmogrod\Primitive\Listt;
+use Widmogrod\Primitive\ListtCons;
/**
* @var callable
* zip takes two lists and returns a list of corresponding pairs. If one input list is short, excess elements of the longer list are discarded.
* zip is right-lazy:
*
- * @param Listt $a
- * @param Listt|null $b
+ * @param Listt $xs
+ * @param Listt|null $ys
* @return Listt
*/
-function zip(Listt $a, Listt $b = null)
+function zip(Listt $xs, Listt $ys = null)
{
- return curryN(2, function (Listt $a, Listt $b): Listt {
+ return curryN(2, function (Listt $xs, Listt $ys): Listt {
try {
- $x = head($a);
- $y = head($b);
- $xs = tail($a);
- $ys = tail($b);
+ $x = head($xs);
+ $y = head($ys);
- return prepend(
- [$x, $y],
- zip($xs, $ys)
- );
+ return ListtCons::of(function () use ($x, $y, $xs, $ys) {
+ return [
+ [$x, $y],
+ zip(tail($xs), tail($ys))
+ ];
+ });
} catch (EmptyListError $e) {
return 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\zip;
class ZipTest 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, $a, $b) {
+ $list = take($n, zip(repeat($a), repeat($b)));
+
+ return length(filter(eql([$a, $b]), $list)) === $n;
+ });
+ }
}