protected function compareValues($needleValue, $haystackValue) {
        $match = [];

        // List of available function names
        $functions = array_map(function($value) {
            return preg_quote($value, '/');
        }, array_keys($this->functions));

        // Dynamic pattern, based on the keys in the functions list
        $pattern = sprintf(
            '/^@(?<function>%s)\((?<params>.*?)\)$/',
            implode('|', $functions)
        );

        if (is_string($needleValue) && $functions && preg_match($pattern, $needleValue, $match)) {
            // Custom function matching
            $function = $match['function'];
            $params = $match['params'];

            try {
                $this->functions[$function]($haystackValue, $params);
                return true;
            } catch (Exception $e) {
                throw new ArrayContainsComparatorException(
                    sprintf(
                        'Function "%s" failed with error message: "%s".',
                        $function,
                        $e->getMessage()
                    ), 0, $e,
                    $needleValue, $haystackValue
                );
            }
        }

        // Regular value matching
        return $needleValue === $haystackValue;
    }