public function normalize(string $string) : string
    {
        if (isset($this->cache[$string])) {
            return $this->cache[$string];
        }

        $result = $this->normalizeChain($string);

        $toCache = array_map(function(RuleInterface $rule) use (&$result) {
            return $result = $rule->apply($result);
        }, $this->rules);

        // Add cache for variants
        array_map(function($index) use ($result) {
            $this->cache[$index] = $result;
        }, $toCache);
        $this->cache[$string] = $result;

        return $result;
    }