Является ли система типов Haskell препятствием для понимания функционального программирования? [закрыто]

33

Я изучаю Haskell с целью понимания функционального программирования, ожидая, что я буду применять полученные знания на других языках (в основном Groovy, Python, JavaScript).

Я выбрал Haskell, потому что у меня сложилось впечатление, что он очень чисто функциональный и не допускает никакой зависимости от состояния.

Я не выбрал изучение Haskell, потому что мне было интересно ориентироваться в чрезвычайно жесткой системе типов.

У меня такой вопрос: является ли сильная система типов необходимым побочным продуктом исключительно чистого функционального языка или это несвязанный выбор дизайна, характерный для Haskell?

Эрик Уилсон
источник
6
Если вы не хотите вводить что-либо явно, вам не нужно ничего вводить явно. Haskell может самостоятельно выводить типы. И это не значит, что у вас будет одна переменная, потенциально хранящая два несовместимых типа.
Анон.
4
@ Да, но твои списки должны быть однородными. Поверьте мне, такие вещи могут мешать, даже с выводом типа.
Эрик Уилсон
13
@FarmBoy, а что не так с использованием Maybe? Java действительно заставляет вас использовать Maybe во всех классах, что странно.
альтернатива
3
И если вы действительно хотите использовать гетерогенный список, вы, конечно, можете использовать алгебраические типы данных.
альтернатива
1
@mathepic в этот момент мы действительно потеряли мой первоначальный вопрос, который был совершенно верным вопросом.
Эрик Уилсон,

Ответы:

40

Я считаю, что понимание системы типов Хаскелла является усилителем понимания функционального программирования.

Суть чисто функционального программирования заключается в том, что в отсутствие побочных эффектов, которые позволяют вам неявно выполнять всевозможные действия, чисто функциональное программирование делает структуру ваших программ намного более явной.

Haskell не позволяет вам совать вещи под ковер, вынуждает вас явно иметь дело со структурой вашей программы, и он учит вас языку для описания этих структур: языку типов. Понимание типов, особенно богатых типов, таких как Haskell, сделает вас лучшим программистом на любом языке.

Если бы Haskell не был строго типизирован, такие понятия, как монады, аппликативные функторы и тому подобное, никогда бы не были применены к программированию.

Waquo
источник
2
Это хороший ответ, мое добавление заключается в том, что хотя система типов поначалу может показаться необычной, позже, когда вы начнете изучать более продвинутые концепции, вы увидите, что есть определенные вещи, которые могут быть выполнены только из-за приверженности этому типу. система (добавьте STM и параллельные данные в список выше). Вещи, которые не были бы начальными в других системах типов, естественно соответствуют системе Haskell. Мой совет: придерживайтесь этого на некоторое время, дайте ему погрузиться в течение долгого времени (это не «зубной» язык).
Тотчас
2
Я знаю, что это супер старый ответ, но я на самом деле не согласен. Я думаю, что, как бы ни были очевидны некоторые вещи в языке, система типов, особенно с такими монадами, как State и Parsec, подметает тонну вещей под ковер. Это на самом деле очень сильно мешает моей способности изучать библиотеки языка.
Саванни Д'Геринель
4
@ SavanniD'Gerinel: Я думаю, что в этом ответе «засовывать вещи под ковер» не означает добавления неявной функциональности (что Хаскелл делает контролируемым образом, например, посредством монад, и которая помогает уменьшить шаблон), а скорее разрешить некоторый фрагмент кода делать то, что не ожидается делать. Например: чистая функция в Haskell никогда не будет иметь побочных эффектов. Период. Во многих других языках вы можете пообещать это в документации функции, но ничто на вашем языке не помешает вам столкнуться с некоторыми побочными эффектами где-то в вашем коде.
Джорджио
33

Наиболее динамически типизируемый функциональный язык - это, возможно, Scheme. Тем не менее, система типов Хаскелла является показателем ее чистоты. Это вопрос «как измерить чистоту?». Система типов Хаскелла позволяет легко отсеивать нечистые действия IO. Для этого вам нужна система статических типов.

Но скажем, система типов Хаскелла не имеет ничего общего с функциональным программированием. Было бы все еще высокомерно утверждать, что система типов не поможет вам в этом образовательном начинании. Система типов Haskell богата и сложна, и тем более интересна по сравнению с системами типов C ++ и OCaml.

Это препятствие? Нет, я думаю, что это актив. Попробуйте подумать, как справиться с ленью Хаскелла, IOнапример.

Логан Капальдо
источник
8
+1 Система типов Хаскелла может стать вашим другом, когда вы привыкнете к ней.
Ларри Коулман
«Для этого вам нужна система статического типа». В самом деле?
Джон Харроп
1
«Тем интереснее по сравнению с системами типов C ++ и OCaml». Вы изучали первоклассные модули высшего порядка OCaml и структурно типизированную систему объектов и полиморфные варианты?
Джон Харроп
2
@JonHarrop или система эффектов или какой-либо способ измерения / оценки чистоты. Да, именно поэтому их интересно сравнивать. Различные варианты делают для разных языков.
Логан Капальдо
20

Clojure имеет динамическую типизацию и почти такой же чистый, как Haskell, поэтому есть хороший аргумент, что система типов Haskell была скорее выбором дизайна, чем абсолютным требованием. У обоих определенно есть свои сильные стороны, поэтому вы можете рассмотреть Clojure, если вам действительно не нравится жесткость Хаскелла (но см. Ниже).

Когда я впервые начал использовать Haskell, я считал систему типов раздражающей и допускал ее только из-за вывода типов. Вскоре я обнаружил, что многие из ошибок типа, которые компилятор жаловался на вещи, которые в любом случае не работали бы, даже если компилятор позволил мне сделать это (например, случайно использовал map вместо concatMap). Затем я обнаружил, что программы, прошедшие проверку типа, обычно были правильными или, по крайней мере, близки к корректным. У меня даже была ленивая фаза, когда я делал рефакторинг, изменяя тип функции и позволяя компилятору сказать мне, что еще нужно было изменить. Наконец, я понял, что система типов Haskell была очень выразительной, и начал разрабатывать мои программы на основе типов. Это Святой Грааль Хаскелла.

Ларри Коулман
источник
Еще одна вещь, которую стоит отметить: я изучил функциональное программирование, используя и Scheme, и Haskell, примерно в одно и то же время (первое для класса, а второе для развлечения). Я обнаружил, что понимание соответствия рекурсии было намного проще при сопоставлении с шаблоном в Haskell, чем при использовании ifs и conds в Scheme, что, я полагаю, переносится и на Clojure.
Тихон Джелвис
@Larry Coleman: +1 за точное описание моего собственного опыта работы с системами типов: сначала C ++, затем Ocaml, а теперь и мой собственный язык Felix. Да, я все еще занимаюсь рефакторингом, преследуя ошибки компилятора.
Иттрилл
8

Система типов Haskell является ключом к его способности изолировать эффекты от чистого кода. Если вы не можете изолировать эффекты другим способом или полностью удалить эффекты, сильная статическая система типов является требованием для чисто функционального программирования.

Haskell - очень хороший пример языка с сильной статической системой типов. Если вы хотите получить широкое и всестороннее образование в области компьютерных наук и, в частности, дизайна языков программирования, Haskell будет отличным выбором в качестве одного из языков, которые вы должны изучать.

Система типов не должна быть огромным препятствием. Люди, которые программируют, как правило, даже при использовании динамических языков, следуют соглашениям ввода, которые могут быть закодированы с использованием системы типов Haskell. Haskell также имеет вывод типов, который облегчает многословие по сравнению с такими языками, как C ++ и Java. Когда вы получаете сообщение об ошибке, компилятор только сообщает вам во время компиляции, что язык с динамическими типами скажет вам во время выполнения.

Противоположностью динамической системы типов является система статических типов, а не система сильных типов. Сильная система типов является противоположностью слабой системы типов.

dan_waterworth
источник
1
Например, C статически, но слабо типизировано. У вас есть типы, но легко полностью подорвать систему типов, поиграться с базовыми машинно-ориентированными представлениями и т. Д. Многие динамически типизированные языки OTOH довольно строго типизированы - мало неявных приведений, мало способов (если таковые имеются) для подрыва системы типов.
Steve314
4

Он сразу говорит вам, когда вы делаете глупые ошибки. Это полезно Я работал в Racket (Схема) в этот последний семестр, и было несколько раз, когда я проходил непарсированный s-exp, где я ожидал, что синтаксический анализатор ast выполняет какую-то функцию в моем интерпретаторе, и он обнаружился только в моем Тестовый набор среднего размера. Если бы у меня была некоторая статическая типизация, это было бы сразу привлечено к моему вниманию.

Конечно, логические ошибки на самом деле не могут быть обнаружены системой типов, но количество способов, которыми вы можете облажаться, значительно уменьшено.

Кроме того, вывод типов позволяет игнорировать систему типов, если вы хотите. Он все еще там, но он не требует активного участия с вашей стороны. Все еще полезно понимать типы ваших функций, но правильный код будет работать нормально.

Чистота Хаскелла закодирована в его системе типов. Монада IO - это конструкция уровня типа, которая предотвращает утечку нечистого кода в чистые функции, поэтому чистота гарантируется системой типов.

Тео белэр
источник
8
Если вы думаете, что можете игнорировать систему типов Haskell, то я думаю, что вы не очень много кодировали Haskell.
Эрик Уилсон
Не игнорируйте столько, сколько игнорируйте, сколько напечатайте функцию, загрузите ее в GHCi и запустите: t on. Но вам все еще нужно будет посыпать некоторые из интегральных или других функций иногда.
Тео Белер
1
Тир, даже с выводом типа, 90% использования и кодирования функций на Haskell сводят проклятые вещи друг с другом, что требует понимания его системы типов и непонятных сообщений об ошибках проверки типов. Даже «: t» не волшебное решение, это просто первый шаг к пониманию того, как заставить программу скомпилироваться.
Андрес Ф.
Ну, некоторые части грязные, я согласен. Я действительно думаю, что числовые вещи в прелюдии могут быть очищены и исправлены, потому что в нынешнем виде это ужасный беспорядок. Но большинство ключевых функциональных аспектов довольно чистые. map, filter, foldr / l и другие забавные функциональные функции работают довольно хорошо.
Тео Белер
2

Будучи «функциональным» языком, означает (помимо прочего), что функции являются первоклассными объектами в языке.

Быть «чистым» языком означает, что функции являются математическими функциями (в отличие от процедур) - при одинаковом вводе они всегда дают одинаковый вывод.

«Чисто функциональный язык» - это тот, в котором соблюдаются оба вышеперечисленных. Я не знаю , о «pure- LY функционального языка».

Сильная система типов - это один чистый способ иметь чистый, но практичный язык. Типы помогают компилятору вычислить оптимизацию, кроме формы, обеспечивающей дальнейшую корректность. (Но это не единственный способ - clojure является чистым, но не имеет такой сильной системы типов, как Haskell.)

Если система типов беспокоит вас, я бы посоветовал вам попробовать более динамичный язык, такой как Scheme, или обойти использование системы вывода типов Haskell.

pyNem
источник
0

Да, система типов - это невероятный актив. Было бы очень трудно даже описать, как работают монады или как некоторые комбинаторы работают без системы типов. Подумайте, сколько учебников по Haskell сначала попросят вас рассмотреть тип рассматриваемой функции с a: t в REPL. Это просто недоступно для динамически типизированного языка. Конечно, вся сложность системы типов все еще там. Монада все еще является монадой. Но язык решил помыть руки и вообще не оказывать никакой помощи. Ты один, приятель. Я не стучу динамически типизированных языков. Я люблю их нежно. Схема является превосходным инструментом. Но вы заметите, что когда мы говорим о таких вещах, как монады в динамических языках, мы часто изобретаем нотациюдля описания типа процедур. Функциональный программист будет сражаться с типами так или иначе. Проверка типов в Haskell просто дает вам хорошие инструменты, чтобы узнать, как это сделать.

Ара Вартанян
источник