/** * @param array $patterns * @return \Closure */ protected static function __match(array $patterns) { return function (...$args) use($patterns) { // [a] -> Bool $patternApplies = function ($pattern) use($args) { /** @noinspection PhpParamsInspection */ return Logic::all(Arrays::zipWith(Lambda::apply(), Arrays::map(self::make(), Arrays::init($pattern)), $args)); }; try { /** @noinspection PhpParamsInspection */ $getMatchedImplementation = Lambda::compose(Arrays::last(), Arrays::first($patternApplies), Arrays::filter(function ($pattern) use($args) { return count($pattern) - 1 === count($args); })); return call_user_func_array($getMatchedImplementation($patterns), $args); } catch (\Exception $e) { throw new IncompletePatternMatchException('Incomplete pattern match expression.'); } }; }