Merge pull request #85 from widmogrod/feature/make-list-more-lazy 4.1.0
authorGabriel Habryn <widmogrod@gmail.com>
Sat, 30 Dec 2017 21:08:36 +0000 (22:08 +0100)
committerGitHub <noreply@github.com>
Sat, 30 Dec 2017 21:08:36 +0000 (22:08 +0100)
Small refactoring

src/Functional/functions.php
src/Functional/infinit.php
src/Functional/listt.php
src/Functional/sublist.php
src/Functional/zipping.php
src/Monad/Maybe/Just.php
src/Monad/Maybe/Maybe.php
src/Monad/Maybe/Nothing.php
src/Primitive/ListtCons.php
src/Primitive/ListtNil.php
test/Functional/ConcatTest.php

index 1012d2f..bed18bb 100644 (file)
@@ -288,7 +288,7 @@ 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)
-                ? ListtCons::of(function () use ($list, $x) {
+                ? new ListtCons(function () use ($list, $x) {
                     return [$x, $list];
                 }) : $list;
         }, fromNil(), $list);
index 7cd02e0..b0dbc95 100644 (file)
@@ -29,7 +29,7 @@ const iterate = 'Widmogrod\Functional\iterate';
 function iterate(callable $fn, $a = null)
 {
     return curryN(2, function (callable $fn, $a): Listt {
-        return ListtCons::of(function () use ($fn, $a) {
+        return new ListtCons(function () use ($fn, $a) {
             return [$a, iterate($fn, $fn($a))];
         });
     })(...func_get_args());
@@ -50,7 +50,7 @@ const repeat = 'Widmogrod\Functional\repeat';
  */
 function repeat($a)
 {
-    return ListtCons::of(function () use ($a, &$list) {
+    return new ListtCons(function () use ($a, &$list) {
         return [$a, repeat($a)];
     });
 }
@@ -102,7 +102,7 @@ function cycle(Listt $xs): Listt
             return cycle($xs);
         }
 
-        return ListtCons::of(function () use ($xs, $cycled, $cycle) {
+        return new ListtCons(function () use ($xs, $cycled, $cycle) {
             return [head($cycled), $cycle($xs, tail($cycled))];
         });
     };
index 3ee5c1d..eb4e549 100644 (file)
@@ -51,7 +51,7 @@ function fromSnapshotIterator(SnapshotIterator $i): Listt
         return fromNil();
     }
 
-    return ListtCons::of(function () use ($i) {
+    return new ListtCons(function () use ($i) {
         return [
             $i->current(),
             fromSnapshotIterator($i->snapshot())
@@ -74,9 +74,7 @@ const fromValue = 'Widmogrod\Functional\fromValue';
  */
 function fromValue($value): Listt
 {
-    return ListtCons::of(function () use ($value) {
-        return [$value, fromNil()];
-    });
+    return ListtCons::of($value);
 }
 
 /**
@@ -115,9 +113,9 @@ const concat = 'Widmogrod\Functional\concat';
  *
  * @return Listt
  */
-function concat(Foldable $xs)
+function concat(Foldable $xs): Listt
 {
-    return foldr(function ($x, Listt $y) {
+    return foldr(function (Foldable $x, Listt $y) {
         return foldr(prepend, $y, $x);
     }, fromNil(), $xs);
 }
@@ -137,7 +135,7 @@ const prepend = 'Widmogrod\Functional\prepend';
 function prepend($x, Listt $xs = null)
 {
     return curryN(2, function ($x, Listt $xs): Listt {
-        return ListtCons::of(function () use ($x, $xs) {
+        return new ListtCons(function () use ($x, $xs) {
             return [$x, $xs];
         });
     })(...func_get_args());
index 0e03281..ee294e9 100644 (file)
@@ -28,7 +28,7 @@ function take(int $n, Listt $xs = null)
             return fromNil();
         }
 
-        return $xs::of(function () use ($n, $xs) {
+        return new $xs(function () use ($n, $xs) {
             return [head($xs), take($n - 1, tail($xs))];
         });
     })(...func_get_args());
index 32ec116..8dffa58 100644 (file)
@@ -30,7 +30,7 @@ function zip(Listt $xs, Listt $ys = null)
             $x = head($xs);
             $y = head($ys);
 
-            return ListtCons::of(function () use ($x, $y, $xs, $ys) {
+            return new ListtCons(function () use ($x, $y, $xs, $ys) {
                 return [
                     [$x, $y],
                     zip(tail($xs), tail($ys))
@@ -61,10 +61,10 @@ function unzip(Listt $xs): array
         [$x, $y] = head($xs);
 
         return [
-            ListtCons::of(function () use ($x, $xs) {
+            new ListtCons(function () use ($x, $xs) {
                 return [$x, unzip(tail($xs))[0]];
             }),
-            ListtCons::of(function () use ($y, $xs) {
+            new ListtCons(function () use ($y, $xs) {
                 return [$y, unzip(tail($xs))[1]];
             }),
         ];
index 5e60a67..1629c74 100644 (file)
@@ -81,4 +81,15 @@ class Just implements Maybe
     {
         return $this->value;
     }
+
+    /**
+     * foldl _ z Nothing = z
+     * foldl f z (Just x) = f z x
+     *
+     * @inheritdoc
+     */
+    public function reduce(callable $function, $accumulator)
+    {
+        return $function($accumulator, $this->value);
+    }
 }
index a249e2c..0f8425d 100644 (file)
@@ -9,6 +9,7 @@ use Widmogrod\FantasyLand;
 
 interface Maybe extends
     FantasyLand\Monad,
+    FantasyLand\Foldable,
     Common\ValueOfInterface,
     FantasyLand\Monoid
 {
index af00a27..91df3dd 100644 (file)
@@ -73,4 +73,15 @@ class Nothing implements Maybe
     {
         return null;
     }
+
+    /**
+     * foldl _ z Nothing = z
+     * foldl f z (Just x) = f z x
+     *
+     * @inheritdoc
+     */
+    public function reduce(callable $function, $accumulator)
+    {
+        return $accumulator;
+    }
 }
index 3cdf8e2..ed0df28 100644 (file)
@@ -12,6 +12,9 @@ class ListtCons implements Listt, \IteratorAggregate
 {
     public const of = 'Widmogrod\Primitive\ListtCons::of';
 
+    /**
+     * @var callable
+     */
     private $next;
 
     /**
@@ -19,7 +22,9 @@ class ListtCons implements Listt, \IteratorAggregate
      */
     public static function of($value)
     {
-        return new static($value);
+        return new self(function () use ($value): array {
+            return [$value, self::mempty()];
+        });
     }
 
     public function __construct(callable $next)
@@ -44,7 +49,7 @@ class ListtCons implements Listt, \IteratorAggregate
      */
     public function map(callable $transformation): FantasyLand\Functor
     {
-        return self::of(function () use ($transformation) {
+        return new self(function () use ($transformation) {
             [$head, $tail] = $this->headTail();
 
             return [$transformation($head), $tail->map($transformation)];
@@ -142,7 +147,7 @@ class ListtCons implements Listt, \IteratorAggregate
         }
 
         if ($value instanceof self) {
-            return self::of(function () use ($value) {
+            return new self(function () use ($value) {
                 [$x, $xs] = $this->headTail();
 
                 return [$x, $xs->concat($value)];
index 2420afe..90ab725 100644 (file)
@@ -11,7 +11,7 @@ class ListtNil implements Listt
 {
     use Common\PointedTrait;
 
-    public const of = 'Widmogrod\Primitive\Listt::of';
+    public const of = 'Widmogrod\Primitive\ListtConst::of';
 
     public function __construct()
     {
index 08c9d1a..3e652cb 100644 (file)
@@ -5,6 +5,8 @@ declare(strict_types=1);
 namespace test\Functional;
 
 use Widmogrod\Functional as f;
+use Widmogrod\Monad\Maybe\Just;
+use Widmogrod\Monad\Maybe\Nothing;
 
 class ConcatTest extends \PHPUnit\Framework\TestCase
 {
@@ -59,6 +61,14 @@ class ConcatTest extends \PHPUnit\Framework\TestCase
                     3
                 ]),
             ],
+            'Just of lists' => [
+                '$array' => Just::of(f\fromIterable(['a', 1, 3])),
+                '$expected' => f\fromIterable(['a', 1, 3]),
+            ],
+            'Nothing of lists' => [
+                '$array' => Nothing::mempty(),
+                '$expected' => f\fromNil()
+            ],
         ];
     }
 }