|
10 | 10 | use Widmogrod\FantasyLand\Functor;
|
11 | 11 | use Widmogrod\FantasyLand\Monad;
|
12 | 12 | use Widmogrod\FantasyLand\Traversable;
|
13 |
| -use Widmogrod\Monad\Identity; |
14 | 13 | use Widmogrod\Primitive\Listt;
|
15 | 14 | use Widmogrod\Primitive\ListtCons;
|
16 | 15 |
|
@@ -457,37 +456,27 @@ function liftA2(
|
457 | 456 | *
|
458 | 457 | * a.k.a haskell >>
|
459 | 458 | *
|
460 |
| - * Sequentially compose two actions, discarding any value produced by the first, like sequencing operators (such as the semicolon) in imperative languages. |
| 459 | + * Sequentially compose two actions, discarding any value produced by the first, |
| 460 | + * like sequencing operators (such as the semicolon) in imperative languages. |
| 461 | + * |
| 462 | + * This implementation allow to **compose more than just two monads**. |
461 | 463 | *
|
462 | 464 | * @param Monad $a
|
463 | 465 | * @param Monad $b
|
464 | 466 | *
|
465 | 467 | * @return Monad
|
466 | 468 | */
|
467 |
| -function sequenceM(Monad $a, Monad $b) |
468 |
| -{ |
469 |
| - return $a->bind(function () use ($b) { |
470 |
| - return $b; |
471 |
| - }); |
472 |
| -} |
473 |
| - |
474 |
| -/** |
475 |
| - * @var callable |
476 |
| - */ |
477 |
| -const sequence_ = 'Widmogrod\Functional\sequence_'; |
478 |
| - |
479 |
| -/** |
480 |
| - * sequence_ :: Monad m => [m a] -> m () |
481 |
| - * |
482 |
| - * @todo consider to do it like this: foldr (>>) (return ()) |
483 |
| - * |
484 |
| - * @param Monad[] $monads |
485 |
| - * |
486 |
| - * @return Monad |
487 |
| - */ |
488 |
| -function sequence_(Monad ...$monads) |
| 469 | +function sequenceM(Monad $a, Monad $b = null): Monad |
489 | 470 | {
|
490 |
| - return reduce(sequenceM, Identity::of([]), fromIterable($monads)); |
| 471 | + return curryN(2, function (Monad ...$monads): Monad { |
| 472 | + return array_reduce($monads, function (?Monad $a, Monad $b) { |
| 473 | + return $a |
| 474 | + ? $a->bind(function () use ($b) { |
| 475 | + return $b; |
| 476 | + }) |
| 477 | + : $b; |
| 478 | + }, null); |
| 479 | + })(...func_get_args()); |
491 | 480 | }
|
492 | 481 |
|
493 | 482 | /**
|
@@ -515,23 +504,6 @@ function traverse(callable $transformation, Traversable $t = null)
|
515 | 504 | })(...func_get_args());
|
516 | 505 | }
|
517 | 506 |
|
518 |
| -/** |
519 |
| - * @var callable |
520 |
| - */ |
521 |
| -const sequence = 'Widmogrod\Functional\sequence'; |
522 |
| - |
523 |
| -/** |
524 |
| - * sequence :: Monad m => t (m a) -> m (t a) |
525 |
| - * |
526 |
| - * @param Traversable|Monad[] $monads |
527 |
| - * |
528 |
| - * @return Monad |
529 |
| - */ |
530 |
| -function sequence(Monad ...$monads) |
531 |
| -{ |
532 |
| - return traverse(identity, fromIterable($monads)); |
533 |
| -} |
534 |
| - |
535 | 507 | /**
|
536 | 508 | * filterM :: Monad m => (a -> m Bool) -> [a] -> m [a]
|
537 | 509 | *
|
|
0 commit comments