То, как это было изложено мне, и то, что я считаю верным после того, как я месяц работал над изучением Haskell, - это тот факт, что функциональное программирование интересным образом крутит ваш мозг: оно заставляет вас думать о знакомых проблемах по-разному. : вместо циклов думайте картами, свертками и фильтрами и т. д. В общем, если у вас есть несколько точек зрения на проблему, это помогает вам лучше рассуждать об этой проблеме и при необходимости менять точки обзора.
Еще одна полезная особенность Haskell - это система типов. Он строго типизирован, но механизм вывода типов делает его похожим на программу Python, которая волшебным образом сообщает вам, когда вы совершили глупую ошибку, связанную с типом. Сообщения об ошибках Haskell в этом отношении несколько отсутствуют, но по мере того, как вы ближе познакомитесь с языком, вы скажете себе: это то, чем должна быть печать!
Это пример , который убедил меня , чтобы узнать Haskell (и мальчик я рад , что я и сделал).
Хорошо, это короткая, читаемая программа. В этом смысле это лучше, чем программа на C. Но чем это так отличается от (скажем) программы на Python с очень похожей структурой?
Ответ - ленивая оценка. В большинстве языков (даже в некоторых функциональных) программа со структурой, подобной приведенной выше, приведет к тому, что весь файл будет загружен в память, а затем снова записан под новым именем.
Haskell «ленив». Он не вычисляет вещи до тех пор, пока это не нужно, и, соответственно , не вычисляет вещи, которые ему никогда не нужны. Например, если бы вы удалили
writeFile
строку, Haskell вообще не стал бы читать что-либо из файла.Как бы то ни было, Haskell понимает, что это
writeFile
зависит от классаreadFile
, и поэтому может оптимизировать этот путь к данным.Хотя результаты зависят от компилятора, при запуске вышеуказанной программы обычно происходит следующее: программа считывает блок (скажем, 8 КБ) первого файла, затем записывает его во второй файл, а затем считывает другой блок из первого файла. файл и записывает его во второй файл и так далее. (Попробуйте запустить
strace
его!)... что очень похоже на то, что делает эффективная реализация копии файла на языке C.
Итак, Haskell позволяет писать компактные, читаемые программы - часто без большого ущерба для производительности.
Еще я должен добавить, что Haskell просто затрудняет написание программ с ошибками. Удивительная система типов, отсутствие побочных эффектов и, конечно же, компактность кода Haskell сокращают количество ошибок как минимум по трем причинам:
Лучший дизайн программы. Снижение сложности приводит к меньшему количеству логических ошибок.
Компактный код. Меньше строк для ошибок.
Ошибки компиляции. Многие ошибки просто недопустимы для Haskell .
Haskell не для всех. Но каждый должен попробовать.
источник
hSetBuffering handle (BlockBuffering (Just bufferSize))
.Data.Bytestring.Lazy.readFile
), которые не имеют ничего общего с Haskell как ленивым (нестрогим) языком. Монады секвенируются - это примерно означает, что «все побочные эффекты исчезают, когда вы убираете результат». Что касается магии "ленивых байтов": это опасно, и вы можете сделать это с похожим или более простым синтаксисом на большинстве других языков.readFile
также выполняет ленивый ввод-выводData.ByteString.Lazy.readFile
. Так что ответ не ошибочный, и это не просто оптимизация компилятора. Действительно, это часть спецификации для Haskell : «readFile
Функция читает файл и возвращает содержимое файла в виде строки. Файл читается лениво, по запросу, как и в случае сgetContents
.»const fs = require('fs'); const [file1, file2] = process.argv.slice(2); fs.createReadStream(file1).pipe(fs.createWriteStream(file2))
. У Bash тоже есть нечто похожее:cat $1 > $2
Вы как бы задаете неправильный вопрос.
Haskell - это не язык, на котором вы смотрите на несколько классных примеров и говорите: «Ага, теперь я понял, вот что делает его хорошим!»
Это больше похоже на то, что у нас есть все эти другие языки программирования, и все они более или менее похожи, а еще есть Haskell, который совершенно другой и дурацкий в том смысле, что это совершенно потрясающе, если вы привыкнете к этому дураку. Но проблема в том, что нужно время, чтобы привыкнуть к этому дураку. Вещи, которые отличают Haskell от почти любого другого даже полуосновного языка:
а также некоторые другие аспекты, которые отличаются от многих основных языков (но разделяются некоторыми):
Как ответили некоторые другие плакаты, сочетание всех этих функций означает, что вы думаете о программировании совершенно по-другому. И поэтому трудно придумать пример (или набор примеров), который адекватно передал бы это Джо, программисту основного направления. Это экспериментальная вещь. (Для аналогии я могу показать вам фотографии моей поездки в Китай в 1970 году, но, посмотрев фотографии, вы все равно не узнаете, каково это было жить там в то время. Точно так же я могу показать вам Haskell 'quicksort', но вы все равно не поймете, что значит быть Haskeller.)
источник
Что действительно отличает Haskell, так это то, что он прилагает усилия для обеспечения функционального программирования. Вы можете программировать в функциональном стиле практически на любом языке, но от этого слишком легко отказаться при первом удобном случае. Haskell не позволяет вам отказываться от функционального программирования, поэтому вы должны довести его до логического завершения, которое является последней программой, о которой легче думать, и которая позволяет избежать целого класса самых сложных типов ошибок.
Когда дело доходит до написания программы для использования в реальном мире, вы можете обнаружить, что Haskell не хватает некоторых практических аспектов, но ваше окончательное решение будет лучше, если вы с самого начала знакомы с Haskell. Я определенно еще не дошел, но до сих пор изучение Haskell было гораздо более познавательным, чем, скажем, Lisp был в колледже.
источник
unsafePerformIO
для людей, которые просто хотят смотреть, как горит мир;)Отчасти проблема заключается в том, что чистота и статическая типизация позволяют использовать параллелизм в сочетании с агрессивной оптимизацией. Параллельные языки сейчас в моде, а многоядерность немного мешает.
Haskell предоставляет больше возможностей для параллелизма, чем любой язык общего назначения, наряду с быстрым компилятором нативного кода. С такой поддержкой параллельных стилей действительно нет конкуренции:
Так что если вы заботитесь о том, чтобы ваша многоядерная среда работала, Haskell есть что сказать. Отличное место для начала - это учебник Саймона Пейтона Джонса по параллельному и параллельному программированию на Haskell .
источник
Программная транзакционная память - довольно крутой способ справиться с параллелизмом. Он намного более гибкий, чем передача сообщений, и не подвержен тупикам, как мьютексы. Реализация STM в GHC считается одной из лучших.
источник
Последний год я изучал Haskell и писал на нем достаточно большой и сложный проект. (Проект представляет собой автоматическую систему торговли опционами, и все, от торговых алгоритмов до анализа и обработки низкоуровневых высокоскоростных потоков рыночных данных, выполняется на Haskell.) Он значительно более краток и проще для понимания (для тех, у кого есть соответствующий фон), чем версия Java, а также чрезвычайно надежный.
Возможно, самой большой победой для меня стала возможность модулировать поток управления через такие вещи, как моноиды, монады и так далее. Очень простой пример - моноид Ordering; в таком выражении, как
где
c1
и так по возвращенииLT
,EQ
илиGT
,c1
возвращаясьEQ
вызывает выражение для продолжения, оценкиc2
; еслиc2
возвращаетсяLT
илиGT
это значение целого иc3
не оценивается. Подобные вещи становятся значительно более изощренными и сложными в таких вещах, как генераторы монадических сообщений и парсеры, где я могу переносить различные типы состояний, иметь различные условия прерывания или, возможно, захочу решить для любого конкретного вызова, действительно ли означает прерывание. «без дальнейшей обработки» или означает «вернуть ошибку в конце, но продолжить обработку для сбора дополнительных сообщений об ошибках».Все это требует времени и, вероятно, некоторых усилий для изучения, и поэтому может быть сложно привести убедительные аргументы в пользу этого для тех, кто еще не знает этих методов. Я думаю, что учебник « Все о монадах» дает довольно впечатляющую демонстрацию одного аспекта этого, но я не ожидал, что кто-то, не знакомый с материалом, уже «поймет его» при первом или даже третьем внимательном чтении.
Как бы то ни было, в Haskell есть много других хороших вещей, но это очень важный вопрос, о котором я не замечаю часто упоминаемого, вероятно, потому, что он довольно сложный.
источник
Для интересного примера вы можете посмотреть: http://en.literateprograms.org/Quicksort_(Haskell)
Что интересно, так это посмотреть на реализацию на разных языках.
Что делает Haskell таким интересным, как и другие функциональные языки, так это то, что вы должны иначе думать о том, как программировать. Например, вы обычно не будете использовать циклы for или while, но будете использовать рекурсию.
Как упоминалось выше, Haskell и другие функциональные языки превосходны в плане параллельной обработки и написания приложений для работы на многоядерных процессорах.
источник
Я не могу привести вам пример, я парень OCaml, но когда я нахожусь в такой ситуации, как вы, любопытство просто захватывает, и мне нужно скачать компилятор / интерпретатор и попробовать. Вы, вероятно, узнаете гораздо больше о сильных и слабых сторонах того или иного функционального языка.
источник
Когда я имею дело с алгоритмами или математическими проблемами, мне очень нравится одна вещь - ленивое вычисление вычислений, присущее Haskell, что возможно только благодаря его строгой функциональной природе.
Например, если вы хотите вычислить все простые числа, вы можете использовать
и в результате получается бесконечный список. Но Haskell будет оценивать его слева направо, поэтому до тех пор, пока вы не пытаетесь сделать что-то, для чего требуется весь список, вы все равно можете использовать его без зависания программы в бесконечности, например:
который суммирует все простые числа меньше 100. Это хорошо по нескольким причинам. Прежде всего, мне нужно написать только одну простую функцию, которая генерирует все простые числа, и тогда я почти готов работать с простыми числами. В объектно-ориентированном языке программирования мне понадобится способ сообщить функции, сколько простых чисел она должна вычислить перед возвратом, или имитировать поведение бесконечного списка с помощью объекта. Другое дело, что, как правило, вы пишете код, который выражает то, что вы хотите вычислить, а не в каком порядке оценивать вещи - вместо этого компилятор делает это за вас.
Это не только полезно для бесконечных списков, но и используется без вашего ведома все время, когда нет необходимости оценивать больше, чем необходимо.
источник
Я согласен с другими, что просмотр нескольких небольших примеров - не лучший способ продемонстрировать Haskell. Но я все равно отдам. Вот молниеносное решение проблем 18 и 67 проекта Эйлера , которые просят вас найти путь с максимальной суммой от основания до вершины треугольника:
Вот полная многоразовая реализация алгоритма BubbleSearch Леша и Митценмахера. Я использовал его для безотходной упаковки больших медиафайлов для архивного хранения на DVD:
Я уверен, что этот код выглядит как случайная тарабарщина. Но если вы прочитаете запись в блоге Митценмахера и поймете алгоритм, вы будете поражены тем, что можно упаковать алгоритм в код, ничего не говоря о том, что вы ищете.
Приведя вам несколько примеров, как вы просили, я скажу, что лучший способ начать ценить Haskell - это прочитать статью Джона Хьюза, которая дала мне идеи, необходимые для написания упаковщика DVD: Почему функциональное программирование имеет значение . Эта статья на самом деле предшествует Haskell, но она блестяще объясняет некоторые идеи, которые заставляют людей любить Haskell.
источник
Для меня привлекательность Haskell - это обещание гарантированной корректности компилятора . Даже если это для чистых частей кода.
Я написал много кода научного моделирования и так много раз задавался вопросом, была ли ошибка в моих предыдущих кодах, которая могла бы сделать недействительной большую часть текущей работы.
источник
Я считаю, что для некоторых задач я невероятно продуктивен с Haskell.
Причина в лаконичном синтаксисе и простоте тестирования.
Вот на что похож синтаксис объявления функции:
Это самый простой способ определения функции.
Если я напишу обратное
Я могу проверить, является ли это обратным для любого случайного ввода, написав
И вызов из командной строки
Что проверит, что все свойства в моем файле сохранены, путем случайного тестирования входных данных сто раз.
Я не думаю, что Haskell - идеальный язык для всего, но когда дело доходит до написания небольших функций и тестирования, я не видел ничего лучше. Если ваше программирование имеет математический компонент, это очень важно.
источник
Если вы можете осмыслить систему типов в Haskell, я думаю, что это само по себе является большим достижением.
источник
в нем нет циклических конструкций. не во многих языках есть эта черта.
источник
Я согласен с теми, кто сказал, что функциональное программирование заставляет ваш мозг смотреть на программирование под другим углом. Я использовал его только как любитель, но я думаю, что это коренным образом изменило мой подход к проблеме. Я не думаю, что был бы так же эффективен с LINQ, если бы не знаком с Haskell (и не использовал генераторы и списки в Python).
источник
Высказывание противоположной точки зрения: Стив Йегге пишет, что языкам Хиндели-Милнера не хватает гибкости, необходимой для написания хороших систем :
Haskell стоит изучить, но у него есть свои недостатки.
источник