use Widmogrod\Primitive\EmptyListError;
use Widmogrod\Primitive\Listt;
+use Widmogrod\Primitive\ListtCons;
+use Widmogrod\Primitive\ListtNil;
/**
* @var callable
/**
* @var callable
*/
+const dropWhile = 'Widmogrod\Functional\dropWhile';
+
+/**
+ *
+ * dropWhile :: (a -> Bool) -> [a] -> [a]
+ *
+ * ```haskell
+ * dropWhile _ [] = []
+ * dropWhile p xs@(x:xs')
+ * | p x = dropWhile p xs'
+ * | otherwise = xs
+ * ```
+ *
+ * @param callable $predicate
+ * @param Listt $xs
+ * @return Listt
+ */
+function dropWhile(callable $predicate, Listt $xs = null)
+{
+ return curryN(2, function (callable $predicate, Listt $xs): Listt {
+ if ($xs instanceof ListtNil) {
+ return $xs;
+ }
+
+ $tail = $xs;
+ do {
+ $x = head($tail);
+ if (!$predicate($x)) {
+ return $tail;
+ }
+
+ $tail = tail($tail);
+ } while ($tail instanceof ListtCons);
+
+ return fromNil();
+ })(...func_get_args());
+}
+
+/**
+ * @var callable
+ */
const span = 'Widmogrod\Functional\span';
/**
--- /dev/null
+<?php
+
+declare(strict_types=1);
+
+namespace test\Functional;
+
+use Widmogrod\Primitive\Listt;
+use function Widmogrod\Functional\dropWhile;
+use function Widmogrod\Functional\fromIterable;
+use function Widmogrod\Functional\fromNil;
+use function Widmogrod\Functional\lt;
+
+class DropWhileTest extends \PHPUnit\Framework\TestCase
+{
+ /**
+ * @dataProvider provideData
+ */
+ public function test_it(
+ Listt $a,
+ callable $fn,
+ Listt $expected
+ ) {
+ $result = dropWhile($fn, $a);
+
+ $r = print_r($result->extract(), true);
+ $e = print_r($expected->extract(), true);
+
+ $this->assertTrue(
+ $result->equals($expected),
+ "$e != $r"
+ );
+ }
+
+ public function provideData()
+ {
+ return [
+ 'should return empty list from when input is empty list' => [
+ '$a' => fromNil(),
+ '$fn' => lt(3),
+ '$expected' => fromNil(),
+ ],
+ 'should provided list when < 100' => [
+ '$a' => fromIterable([1, 2, 3, 4, 5]),
+ '$fn' => lt(100),
+ '$expected' => fromIterable([]),
+ ],
+ 'should return part of finite list' => [
+ '$a' => fromIterable([1, 2, 3, 4, 5]),
+ '$fn' => lt(4),
+ '$expected' => fromIterable([4, 5]),
+ ],
+ 'should return nil list when drop more than in the list' => [
+ '$a' => fromIterable([1, 2, 3, 4, 5]),
+ '$fn' => lt(400),
+ '$expected' => fromNil(),
+ ],
+ ];
+ }
+}