Начало работы с Haskell


755

В течение нескольких дней я пытался обернуть голову вокруг парадигмы функционального программирования в Haskell. Я сделал это, читая учебные пособия и просматривая скринкасты, но, похоже, ничего не изменилось. Теперь, при изучении различных императивных / OO-языков (таких как C, Java, PHP), упражнения стали для меня хорошим способом. Но поскольку я действительно не знаю, на что способен Haskell, и поскольку есть много новых концепций, которые я могу использовать, я не знаю, с чего начать.

Итак, как ты выучил Haskell? Что заставило тебя действительно "сломать лед"? Кроме того, есть хорошие идеи для начала упражнений?


Ответы:


2476

Я собираюсь заказать это руководство по уровню мастерства, которым вы обладаете в Хаскеле, от абсолютного новичка до эксперта. Обратите внимание, что этот процесс займет много месяцев (лет?), Поэтому он довольно долгий.

Абсолютный новичок

Во-первых, Haskell способен на все, с достаточным умением. Он очень быстрый (за моим опытом только C и C ++) и может использоваться для любых целей, от моделирования до серверов, графических приложений и веб-приложений.

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

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

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

Хороший список проблем, которые нужно попробовать, это страница проблем на haskell 99 . Они начинаются очень просто и становятся сложнее по мере продвижения. Это очень хорошая практика, поскольку они позволяют вам практиковать свои навыки в рекурсии и функциях более высокого порядка. Я бы порекомендовал пропустить любые проблемы, которые требуют случайности, поскольку это немного сложнее в Haskell. Проверьте этот SO вопрос в случае , если вы хотите , чтобы проверить свои решения с QuickCheck (см Intermediate ниже).

После того, как вы сделали несколько из них, вы можете перейти к решению некоторых проблем Project Euler . Они отсортированы по тому, сколько людей их выполнили, что является довольно хорошим показателем сложности. Они проверяют вашу логику и Haskell больше, чем предыдущие проблемы, но вы все равно сможете сделать первые несколько. Большое преимущество, которое Haskell имеет с этими проблемами, состоит в том, что целые числа не ограничены в размере. Чтобы решить некоторые из этих проблем, будет полезно прочитать главы 7 и 8, а также узнать о Хаскеле.

начинающий

После этого у вас должны быть достаточно хорошие навыки работы с рекурсией и функциями более высокого порядка, так что сейчас самое время приступить к решению некоторых реальных проблем. Очень хорошее место для начала - Real World Haskell (онлайн-книга, вы также можете приобрести печатную версию). Я обнаружил, что первые несколько глав слишком быстро вводились слишком быстро для тех, кто никогда раньше не занимался функциональным программированием и не использовал рекурсию. Однако с практикой, которую вы имели бы при выполнении предыдущих задач, вы должны найти это совершенно понятным.

Работа с проблемами в книге - отличный способ научиться управлять абстракциями и создавать компоненты многократного использования в Haskell. Это жизненно важно для людей, привыкших к объектно-ориентированному (оо) программированию, так как обычные методы абстракции (классы oo) не появляются в Haskell (в Haskell есть классы типов, но они сильно отличаются от классов oo, больше похожи на интерфейсы oo). ). Я не думаю, что это хорошая идея, чтобы пропустить главы, поскольку каждая из них вводит много новых идей, которые используются в последующих главах.

Через некоторое время вы попадете в главу 14, главу страшных монад (dum dum dummmm). Почти каждый, кто изучает Haskell, испытывает затруднения в понимании монад из-за того, насколько абстрактна эта концепция. Я не могу представить ни одного понятия на другом языке, столь же абстрактного, как монады в функциональном программировании. Monads позволяет объединять многие идеи (такие как операции ввода-вывода, вычисления, которые могут не работать, синтаксический анализ, ...) в рамках одной идеи. Так что не расстраивайтесь, если после прочтения главы о монадах вы на самом деле их не понимаете. Я нашел полезным прочитать много разных объяснений монад; каждый дает новый взгляд на проблему. Вот очень хороший список учебников монады . Я очень рекомендую All About Monads , но другие тоже хороши.

Кроме того, требуется некоторое время, чтобы концепции действительно проникли внутрь. Это приходит через использование, но также и через время. Я обнаружил, что иногда сон на проблему помогает больше, чем что-либо еще! В конце концов, идея сработает, и вы удивитесь, почему вы пытались понять концепцию, которая на самом деле невероятно проста. Это замечательно, когда это происходит, и когда это происходит, вы можете найти Haskell своим любимым языком императивного программирования :)

Чтобы убедиться, что вы в совершенстве понимаете систему типов Haskell, вы должны попытаться выполнить 20 промежуточных упражнений на Haskell . Эти упражнения используют забавные названия функций, таких как «пушистый» и «банановый», и помогают вам лучше понять некоторые базовые концепции функционального программирования, если у вас их еще нет. Хороший способ провести вечер с кучей бумаг, покрытых стрелами, единорогами, сосисками и пушистыми бананами.

промежуточный

Как только вы поймете Monads, я думаю, вы перешли от начинающего программиста на Haskell к промежуточному хаскеллеру. Так куда же идти? Первое, что я бы порекомендовал (если вы еще не изучили их из изучения монад), это различные типы монад, такие как Reader, Writer и State. Опять же, Реальный мир на Haskell и All about monads дает хорошее освещение этого. Для завершения обучения монаде изучение монадных трансформаторов является обязательным. Это позволяет вам объединять разные типы монад (например, читатель и монаду состояния) в одну. Это может показаться бесполезным с самого начала, но после некоторого использования вы будете удивляться, как вы жили без них.

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

Обладая знаниями, которыми вы обладаете сейчас, вы сможете использовать большинство пакетов на cabal (по крайней мере, хорошо документированных), а также большинство библиотек, поставляемых с Haskell. Список интересных библиотек, которые можно попробовать:

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

  • QuickCheck : очень крутая программа тестирования. Что вы делаете, это пишите предикат, который всегда должен быть истинным (например length (reverse lst) == length lst). Затем вы передаете предикат QuickCheck, и он сгенерирует много случайных значений (в данном случае списков) и проверит, что предикат верен для всех результатов. Смотрите также онлайн-руководство .

  • HUnit : модульное тестирование в Haskell.

  • gtk2hs : самый популярный графический интерфейс для Haskell, позволяет писать приложения на gtk на Haskell.

  • happstack : фреймворк для веб-разработки на Haskell. Не использует базы данных, вместо этого хранилище типов данных. Довольно хорошие документы (другие популярные рамки будут хватать и Йесод ).

Кроме того, есть много концепций (например, концепция Монады), которые вы должны в конечном итоге изучить. Это будет легче, чем изучать монады в первый раз, так как ваш мозг привыкнет справляться с уровнем абстракции. Очень хорошим обзором для изучения этих концепций высокого уровня и того, как они сочетаются друг с другом, является Typeclassopedia .

  • Аппликативный: интерфейс похож на Monads, но менее мощный. Каждая монада аппликативна, но не наоборот. Это полезно, поскольку есть некоторые типы, которые являются Аппликативными, но не являются Монадами. Кроме того, код, написанный с использованием функций Applicative, часто более удобен для компоновки, чем написание эквивалентного кода с использованием функций Monad. См. Функторы, Аппликативные Функторы и Моноиды из руководства по изучению языка Haskell.

  • Foldable , Traversable : классы типов, которые абстрагируют многие операции списков, так что те же функции могут быть применены к другим типам контейнеров. Смотрите также объяснение вики на haskell .

  • Monoid : Monoid - это тип, имеющий нулевое (или умеренное) значение, и записанная операция, <>объединяющая два моноида, например, x <> mempty = mempty <> x = xи x <> (y <> z) = (x <> y) <> z. Это так называемые законы идентичности и ассоциативности. Многие типы являются моноидами, такими как числа, с mempty = 0и <> = +. Это полезно во многих ситуациях.

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

  • Массивы : различные изменяемые / неизменяемые массивы в Haskell.

  • ST Monad : позволяет вам писать код с изменяемым состоянием, которое выполняется очень быстро, но остается чистым вне монады. Пройдите по ссылке, чтобы узнать больше.

  • FRP: функциональное реактивное программирование, новый экспериментальный способ написания кода, который обрабатывает события, триггеры, входы и выходы (например, графический интерфейс). Я не знаю много об этом, хотя Разговор Пола Худака о ямпе - хорошее начало.

Есть много новых языковых возможностей, на которые стоит обратить внимание. Я просто перечислю их, вы можете найти много информации о них в Google, на викибуке haskell , на сайте haskellwiki.org и в документации ghc .

  • Классы многопараметрического типа / функциональные зависимости
  • Тип семьи
  • Экзистенциально количественные типы
  • Фантомные типы
  • GADTS
  • другие ...

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

Наконец, вы захотите узнать больше о различных инструментах Haskell. К ним относятся:

  • GHC (и все его особенности)
  • cabal : система пакетов Haskell
  • darcs : распределенная система контроля версий, написанная на Haskell, очень популярная для программ на Haskell.
  • пикша : генератор документации Haskell

Изучая все эти новые библиотеки и концепции, очень полезно написать проект небольшого размера на Haskell. Это может быть что угодно (например, небольшая игра, анализатор данных, веб-сайт, компилятор ). Работая над этим, вы сможете применить многие вещи, которые вы сейчас изучаете. Вы остаетесь на этом уровне целую вечность (это то, где я нахожусь).

эксперт

Вам понадобятся годы, чтобы добраться до этой стадии (привет с 2009 года!), Но отсюда я предполагаю, что вы начнете писать статьи на phd, новые расширения ghc и придумывать новые абстракции.

Получать помощь

Наконец, на любом этапе обучения есть несколько мест для получения информации. Эти:

  • канал #haskell irc
  • в списки рассылки . На них стоит подписаться, чтобы просто прочитать проходящие обсуждения - некоторые из них очень интересные.
  • другие места, перечисленные на домашней странице haskell.org

Вывод

Ну, это оказалось дольше, чем я ожидал ... Во всяком случае, я думаю, что это очень хорошая идея, чтобы стать опытным в Хаскеле. Это занимает много времени, но это в основном потому, что таким образом вы учитесь совершенно новому образу мышления. Это не то же самое, что изучение Ruby после изучения Java, но и изучение Java после изучения C. Кроме того, я обнаружил, что мои навыки объектно-ориентированного программирования улучшились в результате изучения Haskell, поскольку я вижу много новых способов абстрагирования идей.


35
Yay стрелки! Сначала вы позволяете монадам формировать свой мозг, затем стоите на голове и думаете о комонаде, а затем делаете обе одновременно, чтобы получить стрелки :) В Haskell есть много выразительных возможностей, которые можно открыть с помощью уровня типа. программирование тоже.
Эфимент

13
@nanothief Monadболее мощный, но также менее композиционный ... многие люди используют монады, где они могли бы получить более чистый Applicativeкод. Большинство вещей, которые Functors тоже есть Monads, но вы не будете использовать >>=и returnкогда fmapбудет достаточно, потому что последнее приводит к гораздо более простому коду, если вы можете его использовать.
Том Крокетт

8
@pelotom, я добавил ссылку на typeclassopedia, а также лучшие причины использовать Applicative для этого раздела и удалил раздел Functor. Трудно привести концепции Монад и Аппликативов в правильном порядке, поскольку в большинстве учебных материалов (включая RWH) акцент сделан на Монаде. С другой стороны, урок по обучению хакелу прошел долгий путь с тех пор, как я первоначально написал ответ (почти 2 года: O), и он преподает Applicative до Monad, возможно, теперь это должно быть рекомендуемым способом изучения haskell.
Дэвид Миани

2
Отличный совет. Я начал это более года назад, и большую часть времени прохожу промежуточную стадию. Обратная связь: глава монады RWH (глава 14) плохо объяснена. Чтение онлайн-версии RWH полезно, потому что она содержит комментарии из краудсорсинга, которые помогают этой главе. FWIW, вы могли бы изобрести монады, был учебник монады, который работал лучше всего для меня.
Том

6
@tomf: спасибо! Я всегда был поражен тем, насколько хорошо этот ответ получился - прошло почти пять лет с тех пор, как я его написал, но он все еще набирает силу. Мне нужно будет сделать обновление в ближайшее время, хотя, поскольку это немного устарело. Здесь не упоминаются линзы, каналы, виды ограничений, платформа haskell, числа уровней типов, и они являются довольно важными новыми темами с момента написания. Вы правы, что RWH больше не так хорош, он не обновлялся долгое время, и многие примеры не компилируются. Я рад, что это все равно было полезно для тебя.
Дэвид Миани

180

У моего коллеги был хороший опыт в « Learn You a Haskell for Great Good»! ,

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

И проверьте ответы здесь тоже


27
Я второй это. Кроме того, поскольку это неочевидно, вот ссылка на загружаемую версию учебника в формате pdf: learnyouahaskell.com/learnyouahaskell.pdf Веб-дизайн великолепен, но мне также нравится иметь копию для метро.
Телемах

8
Я начал с этого, но мое мнение таково, что вам следует обратиться непосредственно в Real World Haskell. Разница в том, как изучать C из K & R или «C для чайников», который пытается быть простым, но пропускает важные вещи в своем подходе. Я думаю, что лучше просто изложить факты, а не пытаться изучать Haskell «императивным путем».
Джон Смит

7
Я очень люблю это, и я потратил много времени на это и на Real World Haskell. IMO, «Learn You a Haskell» дает более глубокое понимание, чем Real World Haskell, хотя оба они являются большими ресурсами.
Чарли Флауэрс

7
@ abababa22 Я думаю, что сначала лучше прочитать LYAH, а затем отправиться в RWH. ЛЯ не учит тебя только Хаскеллу; он учит вас функциональному программированию. Вы начинаете думать функционально, когда решаете проблемы. Очевидно, что только LYAH будет недостаточно для написания большого приложения, но это заставит вас задуматься. Если вы из императорского фона, это лучший способ, ИМО
Абдулсаттар Мохаммед

4
@Telemachus На заметку: PDF не является окончательной версией, по крайней мере, в ней отсутствует последняя глава.
sdcvvc

103

Вот хорошая книга, которую вы можете прочитать онлайн: Real World Haskell

Большинство программ на Haskell, которые я сделал, предназначались для решения задач Project Euler .

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


2
Реальный мир Haskell в моем опыте великолепен, пока вы не дойдете до главы 5. С тех пор я бы не рекомендовал это.
MasterMastic

Почему @MasterMastic? В чем проблема за пределами главы 5? Я хотел бы знать, прежде чем потратить деньги.
Джей Бланшар

@JayBlanchard В главе 5 вы начинаете получать конкретный пример библиотеки, что приятно, но они говорят вам, что они собираются делать, делают это, но они не объясняют, почему полностью, и не совсем понятно, и есть немало магических шестнадцатеричных литералов. Вы просто проходите через движения. Это была не самая большая проблема для меня, самая большая проблема заключалась в том, что книга в значительной степени зависит от таких сложных и длинных примеров (достаточно длинных, чтобы занять больше, чем целую главу). Вы вряд ли можете просто прочитать части, которые вы хотите. Я думаю, великие авторы, потрясающие знания, но крайне плохое исполнение.
MasterMastic


69

Чтобы добавить ответы других - есть одна полезная, которая поможет вам при кодировании (например, при решении задач проекта Эйлера): Hoogle . Вы можете использовать либо интерфейс командной строки, либо веб-интерфейс .

Командная строка

После установки платформы Haskell обязательно cabal install hoogle

Пример использования Google:

У вас есть функция, f x = 3 * x + 1и вы хотите применить ее (5 :: Int), затем применить ее к результату, к этому результату и т. Д. И получить бесконечный список этих значений. Вы подозреваете, что, возможно, уже существует функция, которая может вам помочь (не специально для вас f).

Эта функция будет иметь тип, (a -> a) -> a -> [a]если это займет f 5илиa -> (a -> a) -> [a] если она берет 5 f(мы предполагаем, что функция предназначена для общих типов, а не только Ints)

$ hoogle "a -> (a -> a) -> [a]"
Prelude iterate :: (a -> a) -> a -> [a]

да, функция, которая вам нужна, уже существует и называется iterate. Вы используете это iterate func 5!

веб интерфейс

Результат для того же примера можно найти здесь .


Найти стандартные функции библиотеки для того, что вам нужно, станет намного проще, если вы поймете, как спросить Hoogle о том, что вам нужно.
Анк-морпорк

57

Программирование Грэма Хаттона на Хаскеле является лаконичным, достаточно тщательным, и его годы преподавания на Хаскеле действительно показывают. Это почти всегда то, с чего я рекомендую людям начать, независимо от того, куда вы идете оттуда.

В частности, глава 8 («Функциональные парсеры») предоставляет реальную основу, необходимую для начала работы с монадами, и я думаю, что это лучшее место для старта, за которым следует All About Monads . (Тем не менее, что касается этой главы, обратите внимание на ошибки на веб-сайте: вы не можете использовать doформу без специальной помощи. Возможно, вы захотите сначала узнать о классах типов и решить эту проблему самостоятельно.)

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


5
Это совершенно недооцененная книга (и ответ). Глава о функциональных синтаксических анализаторах, за которой следует глава о IO, ни в одной из которых даже не упоминаются монады, действительно выглядит как элегантный педагогический подход.
michiakig


31

Я бы предложил присоединиться к каналу #haskell irc и задавать там вопросы. Вот так я и выучил Хаскелл. Если вы пройдете через Real World Haskell, как предложено выше, ответы на ваши вопросы в режиме реального времени очень помогут. Многие умные люди на #haskell пишут на Haskell для удовольствия и для получения прибыли, так что вы получите много хорошего вклада. Попробуй это!


5
+1 - чтобы быть ясным: не изучайте это только с IRC-каналом. Например, не входите и не спрашивайте: «Как мне написать программу на Haskell? Как добавить числа?»
альтернатива

В дополнение к irc freenode в последнее время в чатах Discord активно обсуждается хаскелл.
Правдаadjustr


19

Я могу дополнительно порекомендовать еще одно руководство по Haskell в качестве введения.

Другим хорошим учебным ресурсом (вероятно, на промежуточном уровне), который мне очень помог и, насколько я вижу, в других ответах не упоминалось, является Typeclassopedia Брента Йорджи , которую можно найти в The Monad Reader (выпуск 13)

Он написан в очень доступном стиле и содержит (среди прочего) следующие вводные советы:

Есть два ключа к мудрости опытного хакера из Haskell:

  1. Понять типы.

  2. Получите глубокую интуицию для каждого класса типов и его связь с другими классами типов, подкрепленную знакомством со многими примерами.

Сам Monad Reader является абсолютным сокровищем для функциональных программистов (не только программистов на Haskell).


14

Попробуйте написать в нем простые программы.

Вы можете найти примеры задач в различных учебниках, вероятно.

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

После того, как я решил дюжину, я сломал лед :)

После этого прочитайте много о продвинутых концепциях (Monads, Arrows, IO, рекурсивные структуры данных), потому что haskell бесконечен и их много.


14

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

http://en.wikipedia.org/wiki/Haskell_98_features

Вот хитрые типы классов, включая монады и стрелки

http://www.haskell.org/haskellwiki/Typeclassopedia

для реальных задач и больших проектов запомните эти теги: GHC (наиболее часто используемый компилятор), Hackage (libraryDB), Cabal (система сборки), darcs (еще одна система сборки).

Интегрированная система может сэкономить ваше время: http://hackage.haskell.org/platform/

база данных пакетов для этой системы: http://hackage.haskell.org/

Вики компилятора GHC: http://www.haskell.org/haskellwiki/GHC

После Haskell_98_features и Typeclassopedia, я думаю, вы уже можете найти и прочитать документацию о них сами

Кстати, вы можете протестировать расширение некоторых языков GHC, которое в будущем может стать частью стандарта haskell.

это мой лучший способ изучения хаскелла. Я надеюсь, что это может помочь вам.


13

Я предлагаю вам сначала прочитать учебник BONUS , а затем прочитать Real World Haskell (онлайн бесплатно) . Присоединяйтесь к IRC-каналу #Haskell на irc.freenode.com и задавайте вопросы. Эти люди абсолютно новички дружелюбны, и со временем мне очень помогли. Кроме того, прямо здесь, на SO, это отличное место, чтобы получить помощь с вещами, которые вы не можете понять! Старайтесь не унывать, как только он щелкнет, ваш ум будет взорван.

Учебное пособие BONUS поднимет вам настроение и подготовит вас к захватывающей поездке, которую приносит Real World Haskell. Желаю тебе удачи!


12

Если у вас есть только опыт работы с императивными / OO-языками, я предлагаю использовать более традиционный функциональный язык в качестве трамплина. Haskell действительно отличается, и вам нужно понять много разных концепций, чтобы добраться куда угодно. Я предлагаю сначала заняться языком в стиле ML (например, F #).


Вяз может быть самым близким, более полезным и удобным для новичков из этих альтернатив ...
Педро Роло

1
Я не согласен на прохождение через временный маршрут, как F #. Для меня это все равно, что выпить водку, быстро выпить. Более болезненно, но удовольствие тоже есть. Временные маршруты, только приводит к еще большей путанице для меня.
Правдаadjustr

10

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

Я предлагаю вам посетить страницу Haskell: http://haskell.org . Там у вас есть много материала и много ссылок на самые современные материалы в Haskell, одобренные сообществом Haskell.


2
Извините, но использовать аргумент доктора философии здесь все равно, что сказать, что для хорошего шеф-повара нужно иметь кухонный нож за 300 долларов. Даже Саймон Пейтон Джонс - отец Хаскелла - не имеет докторской степени. Практика и настойчивость - вот что приводит к опыту как здесь, так и в любой другой области.
Петрас Перлис
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.