Improve operations on lists to make them lazy always
authorwidmogrod <widmogrod@gmail.com>
Thu, 21 Dec 2017 17:19:19 +0000 (18:19 +0100)
committerwidmogrod <widmogrod@gmail.com>
Thu, 21 Dec 2017 17:19:19 +0000 (18:19 +0100)
src/Functional/functions.php
src/Functional/sublist.php
test/Functional/RepeatTest.php
test/Functional/TakeTest.php

index cf62b41..6896675 100644 (file)
@@ -10,6 +10,7 @@ use Widmogrod\FantasyLand\Monad;
 use Widmogrod\FantasyLand\Traversable;
 use Widmogrod\Monad\Identity;
 use Widmogrod\Primitive\Listt;
+use Widmogrod\Primitive\ListtCons;
 
 /**
  * @var callable
@@ -285,8 +286,9 @@ function filter(callable $predicate, Foldable $list = null)
     return curryN(2, function (callable $predicate, Foldable $list) {
         return reduce(function (Listt $list, $x) use ($predicate) {
             return $predicate($x)
-                ? append($list, fromValue($x))
-                : $list;
+                ? ListtCons::of(function () use ($list, $x) {
+                    return [$x, $list];
+                }) : $list;
         }, fromNil(), $list);
     })(...func_get_args());
 }
index ef4ec60..54a20d6 100644 (file)
@@ -26,11 +26,9 @@ function take(int $n, Listt $xs = null)
             return fromNil();
         }
 
-        try {
-            return prepend(head($xs), take($n - 1, tail($xs)));
-        } catch (EmptyListError $e) {
-            return fromNil();
-        }
+        return $xs::of(function () use ($n, $xs) {
+            return [head($xs), take($n - 1, tail($xs))];
+        });
     })(...func_get_args());
 }
 
index 6b426a1..ef2b832 100644 (file)
@@ -2,25 +2,39 @@
 
 namespace test\Functional;
 
-use Widmogrod\Primitive\Listt;
-use function Widmogrod\Functional\head;
+use Eris\Generator;
+use Eris\TestTrait;
+use function Widmogrod\Functional\eql;
+use function Widmogrod\Functional\filter;
+use function Widmogrod\Functional\length;
 use function Widmogrod\Functional\repeat;
-use function Widmogrod\Functional\tail;
+use function Widmogrod\Functional\take;
 
 class RepeatTest extends \PHPUnit_Framework_TestCase
 {
-    public function test_it($value = 'ab')
+    use TestTrait;
+
+    public function test_it_should_generate_infinite_list()
     {
-        $result = repeat($value);
-        $this->assertInstanceOf(Listt::class, $result);
+        $this->forAll(
+            Generator\choose(1, 100),
+            Generator\string()
+        )->then(function ($n, $value) {
+            $list = take($n, repeat($value));
+
+            return length($list) === $n;
+        });
+    }
 
-        $this->assertSame($value, head($result));
-        $this->assertSame($value, head(tail($result)));
+    public function test_it_should_generate_repetive_value()
+    {
+        $this->forAll(
+            Generator\choose(1, 100),
+            Generator\string()
+        )->then(function ($n, $value) {
+            $list = take($n, repeat($value));
 
-        $it = $result->getIterator();
-        $this->assertInstanceOf(\Generator::class, $it);
-        $this->assertSame($value, $it->current());
-        $it->next();
-        $this->assertSame($value, $it->current());
+            return length(filter(eql($value), $list)) === $n;
+        });
     }
 }
index 149e02e..927b59c 100644 (file)
@@ -24,7 +24,8 @@ class TakeTest extends \PHPUnit_Framework_TestCase
         $e = print_r($expected->extract(), true);
 
         $this->assertTrue(
-            $result->equals($expected)
+            $result->equals($expected),
+            "$e != $r"
         );
     }