Skip to content

Instantly share code, notes, and snippets.

@timacdonald
Last active December 13, 2021 08:30
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save timacdonald/7847ef40989ab80b41ce119558ec2074 to your computer and use it in GitHub Desktop.
Save timacdonald/7847ef40989ab80b41ce119558ec2074 to your computer and use it in GitHub Desktop.
Transducers
<?php
declare(strict_types=1);
namespace Transducers;
use Closure;
function compose(array $reducers): Closure
{
$reducers = array_reverse($reducers);
return fn (Closure $step) =>
fn ($accumulator, $current) =>
array_reduce(
$reducers,
fn ($accumulator, $current) => $current($accumulator),
$step
)($accumulator, $current);
}
function filter(Closure $predicate): Closure
{
return fn (Closure $step) =>
fn ($accumulator, $current) =>
$predicate($current)
? $step($accumulator, $current)
: $accumulator;
}
function map(Closure $callback): Closure
{
return fn (Closure $step) =>
fn ($accumulator, $current) =>
$step($accumulator, $callback($current));
}
<?php
declare(strict_types=1);
use function Transducers\compose;
use function Transducers\filter;
use function Transducers\map;
$double = fn ($value) => $value * 2;
$isEven = fn ($value) => ($value % 2) === 0;
$doubleEvens = compose([
filter($isEven),
map($double),
]);
$xform = $doubleEvens(function ($accumulator, $current) {
$accumulator[] = $current;
return $accumulator;
});
$result = array_reduce([2, 2, 3, 4], $xform, []);
// [4, 4, 8]
@timacdonald
Copy link
Author

This was fun. Do not recommend.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment