Для чего полезны проекции типов в Scala? Почему система типов Scala поддерживает как проекции типов, так и типы, зависимые от пути? Что было обоснование этого дизайнерского решения?