Beispiel #1
0
/**
 * Takes a callable, then flips the two next arguments before calling the function
 * @param callable
 * @return \Closure f(a, b, ....z) -> f(b,a, ... z)
 */
function flip(callable $hof)
{
    // Use the variadic internal static form of curry. We don't want to eat the rest of the args.
    return __PRIVATE__::curryGiven([], 2, function (...$args) use($hof) {
        $temp = $args[0];
        $args[0] = $args[1];
        $args[1] = $temp;
        return call_user_func_array($hof, $args);
    });
}
Beispiel #2
0
namespace PHPixme;

/**
 * Takes two functions and has the first consume the output of the second, combining them to a single function
 * @param callable $hofSecond
 * @param callable = $hofFirst
 * @return \Closure
 * @sig (Unary Callable(y -> z), ..., Unary Callable(a -> b), Callable (*->a)) -> \Closure (* -> a)
 */
function combine(callable $hofSecond = null, callable $hofFirst = null)
{
    return call_user_func_array(__PRIVATE__::$instance[combine], func_get_args());
}
const combine = __NAMESPACE__ . '\\combine';
__PRIVATE__::$instance[combine] = __PRIVATE__::curryGiven([], 2, function () {
    $combine = func_get_args();
    foreach ($combine as $idx => $hof) {
        __CONTRACT__::argIsACallable($hof, $idx);
    }
    $combineHead = end($combine);
    $combineTail = array_slice($combine, 0, -1);
    $combineTailSize = count($combineTail);
    return function () use($combineHead, $combineTail, $combineTailSize) {
        $acc = call_user_func_array($combineHead, func_get_args());
        for ($index = $combineTailSize - 1; -1 < $index; $index -= 1) {
            $acc = call_user_func($combineTail[$index], $acc);
        }
        return $acc;
    };
});
Beispiel #3
0
<?php

namespace PHPixme;

/**
 * Take a callable and produce a curried \Closure
 * @param int $arity
 * @param callable = $hof
 * @return \Closure
 * @sig Integer -> Callable (*-> x) -> \Closure (* -> x)
 */
function curry($arity = null, callable $hof = null)
{
    return call_user_func_array(__PRIVATE__::$instance[curry], func_get_args());
}
const curry = __NAMESPACE__ . '\\curry';
__PRIVATE__::$instance[curry] = __PRIVATE__::curryExactly2(function ($arity, $callable) {
    __CONTRACT__::argIsAPositiveOrZeroInt($arity);
    __CONTRACT__::argIsACallable($callable, 1);
    // The function is static so that is easier to recurse,
    // as it shares no state with itself outside its arguments.
    return __PRIVATE__::curryGiven([], $arity, $callable);
});
Beispiel #4
0
<?php

namespace PHPixme;

/**
 * @param $hofFirst
 * @param callable $hofSecond
 * @return mixed
 * @sig (Callable (* -> a) -> Unary Callable ( a -> b ), ..., Unary Callable (y -> z)) -> \Closure (*->z)
 */
function pipe(callable $hofFirst = null, callable $hofSecond = null)
{
    return call_user_func_array(__PRIVATE__::$instance[pipe], func_get_args());
}
const pipe = __NAMESPACE__ . '\\pipe';
__PRIVATE__::$instance[pipe] = __PRIVATE__::curryGiven([], 2, function ($x) {
    $pipe = func_get_args();
    foreach ($pipe as $index => $value) {
        __CONTRACT__::argIsACallable($value, $index);
    }
    $pipeTail = array_splice($pipe, 1);
    return function () use($x, $pipeTail) {
        $acc = call_user_func_array($x, func_get_args());
        $_pipeTail = $pipeTail;
        foreach ($_pipeTail as $hof) {
            $acc = call_user_func($hof, $acc);
        }
        return $acc;
    };
});