namespace PHPixme; /** * @param callable $hof * @param \Traversable= $traversable * @return \Closure|mixed * @sig Callable (a, b -> a) -> \Traversable[a,b] -> a */ function reduceRight($hof = null, $traversable = null) { return call_user_func_array(__PRIVATE__::$instance[reduceRight], func_get_args()); } const reduceRight = __NAMESPACE__ . '\\reduceRight'; __PRIVATE__::$instance[reduceRight] = __PRIVATE__::curryExactly2(function ($hof, $arrayLike) { __CONTRACT__::argIsACallable($hof); __CONTRACT__::argIsATraversable($arrayLike, 1); if ($arrayLike instanceof ReducibleInterface) { return $arrayLike->reduceRight($hof); } // Equalize the usefulness $array = __CONTRACT__::isNonEmpty(__PRIVATE__::traversableToArray($arrayLike)); $output = end($array); $value = prev($array); // Traverse using the internal pointer to avoid creating additional work while (($key = key($array)) !== null) { $output = call_user_func($hof, $output, $value, $key, $arrayLike); $value = prev($array); } return $output; });
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; }; });
<?php namespace PHPixme; /** * Group a traversable by a return value, separating them out into [groupName=>[value...]] * @param callable $fn * @param array|\Traversable $arrayLike * @return array|\Closure */ function group($fn = null, $arrayLike = null) { return call_user_func_array(__PRIVATE__::$instance[group], func_get_args()); } const group = __NAMESPACE__ . '\\group'; __PRIVATE__::$instance[group] = __PRIVATE__::curryExactly2(function ($fn, $arrayLike) { __CONTRACT__::argIsACallable($fn); __CONTRACT__::argIsATraversable($arrayLike, 1); if ($arrayLike instanceof GroupableInterface) { return $arrayLike->group($fn); } $output = []; foreach (__PRIVATE__::protectTraversable($arrayLike) as $key => $value) { $output[call_user_func($fn, $value, $key, $arrayLike)][] = $value; } return $output; });
<?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); });
<?php namespace PHPixme; // -- Starling -- /** * Starling * This combinator takes two functions and applies the third across both. * The first operand must return a function, which will relieve the result of the second. * Useful for combining mappings of the same data together * @param callable $x * @param callable $y * @param mixed $z * @return \Closure|mixed * @sig Callable x -> Callable y -> z -> a */ function S($x = null, $y = null, $z = null) { return call_user_func_array(__PRIVATE__::$instance[S], func_get_args()); } const S = __NAMESPACE__ . '\\S'; __PRIVATE__::$instance[S] = __PRIVATE__::curryExactly3(function ($x, $y, $z) { __CONTRACT__::argIsACallable($x); __CONTRACT__::argIsACallable($y, 1); return call_user_func(__CONTRACT__::composedIsACallable(call_user_func($x, $z)), call_user_func($y, $z)); });
<?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; }; });