public function test_it_should_return_new_map()
 {
     $collection = Listt::of([['id' => 1, 'name' => 'One'], ['id' => 2, 'name' => 'Two'], ['id' => 3, 'name' => 'Three']]);
     $result = $collection->map(function ($a) {
         return $a['id'] + 1;
     });
     $this->assertEquals(Listt::of([2, 3, 4]), $result);
 }
 public function test_foldr()
 {
     $list = Listt::of([1, 2, 3, 4]);
     $result = f\foldr(function ($accumulator, $value) {
         return f\concatM($accumulator, Listt::of([$value + 1]));
     }, Listt::of([]), $list);
     $this->assertEquals($result, Listt::of([5, 4, 3, 2]));
 }
 public function test_it_should_sum_all_from_one_list_with_single_element()
 {
     // sum <$> [1, 2] <*> [4, 5]
     $sum = f\curryN(2, 'example\\sum');
     $a = Listt::of([1, 2]);
     $b = Listt::of([4, 5]);
     $result = f\map($sum, $a)->ap($b);
     $this->assertEquals(Listt::of([5, 6, 6, 7]), $result);
 }
 public function test_it_should_combine_two_lists()
 {
     // [1,2] >>= \n -> ['a','b'] >>= \ch -> return (n,ch) == [(1,'a'),(1,'b'),(2,'a'),(2,'b')]
     $result = Listt::of([1, 2])->bind(function ($n) {
         return Listt::of(['a', 'b'])->bind(function ($x) use($n) {
             return [[$n, $x]];
         });
     });
     $this->assertEquals(Listt::of([[1, 'a'], [1, 'b'], [2, 'a'], [2, 'b']]), $result);
 }
 /**
  * @dataProvider provideData
  */
 public function test_it_should_extract_elements_which_exists_alternative_solution($data)
 {
     // $get :: String a -> Maybe [b] -> Maybe b
     $get = function ($key) {
         return f\bind(function ($array) use($key) {
             return isset($array[$key]) ? m\just($array[$key]) : m\nothing();
         });
     };
     $result = Listt::of($data)->map(Maybe\maybeNull)->bind($get('meta'))->bind($get('images'))->bind($get(0));
     $this->assertEquals(Listt::of([m\just('//first.jpg'), m\just('//third.jpg'), m\nothing()]), $result);
 }
 public function test_it_should_apply_every_function_in_collection_with_every_item_in_second()
 {
     $collectionA = Listt::of([function ($a) {
         return 3 + $a;
     }, function ($a) {
         return 4 + $a;
     }]);
     $collectionB = Listt::of([1, 2]);
     $result = $collectionA->ap($collectionB);
     $this->assertInstanceOf(Listt::class, $result);
     $this->assertEquals(Listt::of([4, 5, 5, 6]), $result);
 }
/**
 * foldr :: Foldable t => (a -> b -> b) -> b -> t a -> b
 *
 * Foldr is expresed by foldl (reduce) so it loose some properties.
 * For more reading please read this article https://wiki.haskell.org/Foldl_as_foldr
 *
 * @param callable $callable Binary function ($value, $accumulator)
 * @param mixed $accumulator
 * @param Foldable $foldable
 *
 * @return mixed
 */
function foldr(callable $callable, $accumulator = null, Foldable $foldable = null)
{
    return call_user_func_array(curryN(3, function (callable $callable, $accumulator, Foldable $foldable) {
        return reduce($callable, $accumulator, reduce(function ($accumulator, $value) {
            return concatM(Listt::of([$value]), $accumulator);
        }, Listt::of([]), $foldable));
    }), func_get_args());
}
 private function randomize()
 {
     return Listt::of(array_keys(array_fill(0, rand(20, 100), null)));
 }
 public function test_it_traverse_nothing()
 {
     $list = Listt::of([1, 2, 3, 4]);
     $result = f\traverse('example\\value_is', $list);
     $this->assertEquals(m\nothing(), $result);
 }