/**
* @return mixed|callable
*/
public static function zipWith()
{
$args = func_get_args();
/**
* Like zip but applies the callable to each value before yielding
*
* @param callable $callable
* @param Generator|array $a
* @param Generator|array $b
*
* @return \Generator
* @throws Exception
*/
$_zipWith = function ($callable, $a, $b) {
Exception::assertCallable($callable);
Exception::assertList($a);
Exception::assertList($b);
if (is_array($a)) {
$a = new \ArrayIterator($a);
}
if (is_array($b)) {
$b = new \ArrayIterator($b);
}
for ($a->rewind(), $b->rewind(); $a->valid() && $b->valid(); $a->next(), $b->next()) {
(yield self::apply($callable, [$a->current(), $b->current()]));
}
};
return call_user_func_array(self::curry3($_zipWith), $args);
}