Недостатки системы типов Scala по сравнению с Haskell?
Я читал, что система типов Scala ослаблена совместимостью с Java и поэтому не может выполнять некоторые из тех же функций, что и система типов в Haskell. Это правда? Это слабость из-за стирания типа или я ошибаюсь во всех отношениях? Является ли это различие причиной того, что у Scala нет классов типов?
6 ответов
Большая разница в том, что Scala не имеет глобального вывода типа Хиндли-Милнера, а вместо этого использует форму локального вывода типа, требуя, чтобы вы указали типы для параметров метода и возвращаемый тип для перегруженных или рекурсивных функций.
Это не обусловлено стиранием типа или другими требованиями JVM. Все возможные трудности здесь могут быть преодолены, и были, просто рассмотрите Jaskell - http://docs.codehaus.org/display/JASKELL/Home
Вывод HM не работает в объектно-ориентированном контексте. В частности, когда используется тип-полиморфизм (в отличие от специального полиморфизма классов типов). Это очень важно для надежного взаимодействия с другими библиотеками Java и (в меньшей степени) для получения наилучшей возможной оптимизации от JVM.
Неверно утверждать, что у Haskell или Scala более сильная система типов, просто они разные. Оба языка раздвигают границы для программирования на основе типов в разных направлениях, и каждый язык обладает уникальными преимуществами, которые трудно дублировать в другом.
Система типов Scala отличается от системы типов Haskell, хотя концепции Scala иногда напрямую связаны с сильными сторонами Haskell и его знающим сообществом исследователей и специалистов.
Конечно, работа на виртуальной машине, в первую очередь не предназначенная для функционального программирования, создает некоторые проблемы совместимости с существующими языками, предназначенными для этой платформы. Поскольку большинство рассуждений о типах происходит во время компиляции, ограничения Java (как языка и как платформы) во время выполнения не должны вызывать беспокойства (кроме Erasure Type, хотя именно эта ошибка, кажется, делает интеграцию в Java экосистема более бесшовная).
Насколько я знаю, единственным "компромиссом" на уровне системы типов с Java является специальный синтаксис для обработки необработанных типов. Хотя Scala даже не допускает использование необработанных типов, она принимает старые файлы классов Java с этой ошибкой. Может быть, вы видели код как List[_]
(или более длинный эквивалент List[T] forSome { type T }
). Это функция совместимости с Java, но внутренне она рассматривается как экзистенциальный тип и не ослабляет систему типов.
Система типов Scala поддерживает классы типов, хотя и более многословно, чем Haskell. Я предлагаю прочитать этот документ, который может создать другое впечатление об относительной силе системы типов Scala (таблица на странице 17 служит хорошим списком очень мощных концепций системы типов).
Необязательно связан с мощью системы типов подход, используемый компиляторами Scala и Haskell для вывода типов, хотя он оказывает некоторое влияние на то, как люди пишут код. Наличие мощного алгоритма вывода типов может позволить написать более абстрактный код (вы можете сами решить, хорошо ли это во всех случаях).
В конце концов, система типов Scala и Haskell основана на стремлении предоставить своим пользователям лучшие инструменты для решения своих проблем, но они пошли разными путями к этой цели.
Еще один интересный момент, который следует учитывать, - это то, что Scala напрямую поддерживает классический ОО-стиль. Это означает, что существуют отношения подтипов (например, List является подклассом Seq). И это делает вывод типа более сложным. Добавьте к этому тот факт, что вы можете смешивать черты в Scala, что означает, что данный тип может иметь несколько отношений супертипа (что делает его еще более сложным)
Scala не имеет ранговых типов, хотя в некоторых случаях возможно обойти это ограничение.
У меня мало опыта с Haskell, но самое очевидное, что я отмечаю, что система типов Scala, отличающаяся от Haskell, - это вывод типов.
В Scala нет глобального вывода типа, вы должны явно указать тип аргументов функции.
Например, в Scala вам нужно написать это:
def add (x: Int, y: Int) = x + y
вместо
add x y = x + y
Это может вызвать проблемы, когда вам нужна общая версия функции add, которая работает со всеми типами типов, имеет метод "+". Для этого есть обходной путь, но он станет более многословным.
Но в реальном использовании я обнаружил, что система типов Scala является достаточно мощной для ежедневного использования, и я почти никогда не использую эти обходные пути для универсального, возможно, это потому, что я из мира Java.
И ограничение явного объявления типа аргументов не обязательно является плохой вещью, вам все равно нужно это документировать.
Ну что они сводятся по Тьюрингу?
См. Страницу Олега Киселева http://okmij.org/ftp/... Лямбда-исчисление можно реализовать в системе типов Хаскелла. Если Scala может сделать это, то в некотором смысле система типов Haskell и система типов Scala вычисляют одинаковые типы. Вопросы: насколько естественен один над другим? Насколько элегантно одно над другим?