Skip to content

Proposal: applyTo() utility function #13

@tobia

Description

@tobia

Hello and thank you for writing this library.

Whenever I'm defining a pipeline of functions to be applied immediately to a starting value, instead of being given a name and saved for later, I use the following utility function:

/**
 * Accept an input and some callables, then apply the callables in order.
 *
 * @param   $input      Input to the computation.
 * @param   $callables  Any number of callables to be composed using pipe().
 * @return              Final result of the computation.
 */
function applyTo($input, callable ...$callables) {
    return f\pipe(...$callables)($input);
}

This enables a Bash-like, left-to-right / top-to-bottom style of pipeline definition and application, for those (like me) who find it more readable than the backwards style of compose():

$res = applyTo([1,2,3,4],            // <- input
    c\filter(fn ($x) => $x > 2),   // <- first step
    c\map(fn ($x) => $x * 3),      // ...
    c\toArray,                     // <- last step
);

assert($res == [9, 12]);

Here is a more complex example, showing how to use one applyTo() inside another:

$pages = [
    (object)['slug'=>'about', 'name'=>'About Us'],
    (object)['slug'=>'about', 'name'=>'About You'],
    (object)['slug'=>'news',  'name'=>'Latest News'],
];

$duplicate = applyTo($pages,
    c\groupBy(fn ($page) => $page->slug),
    c\filter(fn ($group) => count($group) > 1),
    c\map(fn ($pages) =>
        "Pages with slug '{$pages[0]->slug}': " . applyTo($pages,
            c\map(fn ($page) => "({$page->name})"),
            c\join(", "),
        )
    ),
    c\join(". "),
);

assert($duplicate == "Pages with slug 'about': (About Us), (About You)");

Do you have any suggestions / critiques? Would you accept a pull request for this function?

I also thought about other calling styles, such as curried: applyTo($input)($fn1, $fn2...) or array: applyTo($input, [$fn1, $fn2...]) but ultimately I decided to keep things simple.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions