* All translation references added to all other translation documents which have "non-speakers" section * Remove link to English in README.md
39 KiB
Як вивчати Haskell
Цей документ є рекомендованим шляхом вивчання Haskell, який ґрунтується на досвіді допомоги іншим. Список рекомендацій від одного з авторів HaskellBook.
Інші переклади
Не намагайтесь одразу зрозуміти все. Краще не зупиняйтесь і продовжуйте рухатись далі!
Ком’юніті
Наш канал в IRC - #haskell-beginners
на серверах Freenode.
Веб-інтерфейс для IRC можна знайти тут.
Пов'язані з Haskell поштові розсилки.
Отримати допомогу українською можна в Slack-чаті KyivHaskell або Gitter-чаті dou-ua/fp.
Норми та правила спільноти
Прочитайте допис Кріса Дона присвячений навчанню
Будьте ввічливими та доброзичливими. Грубість та неввічливість відлякують людей і відбивають в них бажання співпрацювати.
Легковажна і зверхня критика не сприймається адресатом і задовільняє лише того, хто критикує.
Не описуйте речі як "легкі" або "тривіальні". Люди, що важко працюють над вдосконаленням своїх знань, через такі ремарки будуть почуватись жахливо. Зазвичай повільно навчаються ті, хто водночас є найбільш стараними учнями і це є радше приводом для радощів!
Не треба удаваного здивування. Не зображуйте подив, коли хтось каже, що він чогось не знає. Люди знов таки будуть почуватись жахливо, а ви не досягнете майже нічого окрім різкості.
Ніяких "Насправді". Хтось каже щось, що майже, але не цілковито, правильне, і тут ви кажете "насправді..." і додаєте малосуттєве виправлення. Особливо це дратує, коли виправлення має мало спільного з темою обговорення. Це не значить, що наша спільнота не орієнтована на пошук істини чи що ми не вважаємо, що точність важлива. Майже усі "насправді" призначені для самозвеличення, а не для пошуку істини.
Намагайтесь не забігати поперед учня. Не треба періодично влізати із порадами якщо ви бачите, що людина працює над проблемою. Дайте їй шанс подолати проблему самотужки, а за потреби за порадою. Уникнення втручаннь є одним з найважливіших задумів #haskell-beginners.
Ніяких -измів, навіть замаскованих. Расизм, сексизм, гомофобія, трансфобія та інші види упередженності у жодному разі не припускаються.
Якщо ви не займаєтесь відвертим тролінгом, то на каналі ви можете отримати зауваження. Завжди зважайте на те, що канал створено для людей, які або самотужки вивчають Haskell або вчать програмуванню на ньому інших.
Встановлення Haskell
Використовуйте Stack для початку роботи з Haskell
Встановіть Stack щоби встановити GHC та збирати свої проекти.
Якщо ви не знаєте нічого про Stack та хотіли би отримати огляд — подивіться цей відео туторіал.
НЕ ВСТАНОВЛЮЙТЕ HASKELL PLATFORM
Замість того, щоб слідувати інструкції на Haskell.org, використовуйте Stack.
Чому не Haskell Platform?
https://mail.haskell.org/pipermail/haskell-community/2015-September/000014.html
Як мені слід вивчати Haskell?
Основна рекомендація - прочитати лекції та пройти всі вправи та домашні завдання версії Spring 13 курсу cis1940, потім пройти курс FP (посилання на обидва курси нижче). Все інше можна вважати додатковим матеріалом, який згадується для того, щоб ви знали, де шукати.
Альтернативно...
@dmvianna хотіла, щоби я вам передав, що це лише ресурси для безкоштовного вивчення. Якщо ви хочете купити книгу, ми сердешно рекомендуємо нашу власну Haskell Book!! Ця книга замінює необхідність всіх інших ресурсів, перелічених тут.
Курс cis1940 від Yorgey
ПОЧНІТЬ З ЦЬОГО, це головний рекомендований метод занурення в Haskell.
Доступний онлайн.
Курс Брента Йорґі (Brent Yorgey) - найкращій курс, який я знайшов на сьогодні. Особлива цінність цього курсу в тому, що він не тільки навчить вас писати базові речі на Haskell, але й допоможе зрозуміти комбінатори парсера.
Не слід починати з cis1940 тільки в тому випадку, коли ви не програміст або програміст із маленьким досвідом. В цьому разі почніть з цієї книги Томпсона, після чого переходьте до cis1940.
Курс FP
Цей курс рекомендовано до вивчання після закінчення курсу cis1940
Матеріали курсу доступні на github.
Цей курс посилить та збагатить ваш досвід через реалізацію абстракцій, які були введені в курсі cis1940. Такий практичний досвід є критичним, так як він надасть вам впевненості у повсякденному використанні Functor/Applicative/Monad/ін. у Haskell. Проходження cis1940, а після нього FP - головна рекомендація цієї інструкції. Саме так ми вчимо Haskell всіх бажаючих.
Додаткові матеріали після курсів cis1940 та FP
Додатковий матеріал на більш складні теми
Курс cs240h доступний онлайн.
Цей курс, створений Брайаном О'Салліваном(https://github.com/bos) за мотивами його викладацької діяльності в університеті Стенфорду. Щоб уявити хто це, зауважте такий факт: ледь не половина бібліотек, від яких залежить майже будь-яка програма на Haskell, містить його ім'я серед авторів. Після проходження курсу Йорґі особливо зверніть увагу на модулі присвячені фантомним типам, контролю потоку інформації, розширенням мови, сумісному виконанню, pipes та лінзам.
Ресурси, що розглядають конкретні теми Haskell
На додаток пропонуються матеріали, присвячені поглибленному вивчанню більш складних тем, а також обговорюють інструменти розробки та текстові редактори. Ці матеріали не були випробувані у навчальних цілях так ретельно, як cis1940 та FP, але їх список можна передивитись
Конкретні питання по Haskell
Що роблять синтаксичні конструкції <-
/ do
/ спискове включення?
Чудова стаття розглядає ці питання.
Щоб зрозуміти списки та згортання списків (fold)
Щоб вивчити деякі відомі класи типів
Матеріал, що дуже корисний для розуміння Functor
, Applicative
, Monad
, Monoid
та інших класів типів в цілому, а також трохи специіфчної для Haskell теорії категорій.
Розуміння базових повідомлень про помилки від Haskell
Лінивість, строгість, стримана рекурсія
-
Книга Марлоу (Marlow) про паралелизм та сумісне виконання має одне з найкращих введень в лінивість та нормальні форми. Якщо матеріал з неї не буде засвоюватись, зверніться до інших джерел.
-
Питання на Stack Overflow 'Does haskell have laziness?'
-
Слайди з виступу Johan Tibell на тему reasoning about laziness.
Маленька демонстрація
let a = 1 : a -- guarded recursion, (:) is lazy and can be pattern matched.
let (v : _) = a
> v
1
> head a -- head a == v
1
let a = 1 * a -- not guarded, (*) is strict
> a
*** Exception: <<loop>>
IO
-
Haddocks for System.IO.Unsafe.unsafePerformIO Обов'язково прочитайте документацію та перегляньте реалізацію unsafeDupablePerformIO
Коментар з обговорення в Reddit від glaebhoerl
Цікаве зауваження: GHC мусить приховувати представлення токену стану за абстрактним типом IO через те, що токен стану завжди мусить використовуватись лінійно (не дублюватись або бути скинутим), але система типів не може примушувати до цього. Інша Haskell-подібна мова під назвою Clean має систему унікальних типів (які подібні до лінійних типів і, можливо, інші в аспектах, які я не знаю), і вони надають можливість прямої передачі World, маючи (не абстрактну) монаду IO тільки для зручності.
Оригінал:
Interesting side note: GHC needs to hide the state token representation behind an abstract IO type because the state token must always be used linearly (not duplicated or dropped), but the type system can't enforce this. Clean, another lazy Haskell-like language, has uniqueness types (which are like linear types and possibly different in ways I'm not aware of), and they expose the World-passing directly and provide a (non-abstract) IO monad only for convenience.
Монади та їх трансформери
Не займатесь цим доки ви не розумієете класи типів, Monoid, Functor, Applicative!
Самотужки реалізуйте бібліотечні монади (List, Maybe, Cont, Error, Reader, Writer, State) для того, щоб зрозуміти їх краще. Тоді, наприклад, напишіть монадний інтерпретатор невеликої мови виразів за допомогою Monad Transformers Step by Step (згадується також нижче, у розділі 'трансформери монад').
Написання декількох інтерпретаторів простою зміною монад для зміни семантики може надати додаткового розуміння про те, що відбувається.
Також заново реалізуйте Control.Monad
. Функції накшталт mapM
чи sequence
є чудовою можливістю набути практики з написання узагаленного монадічного коду.
У якості путівника можна також використати курс FP, частиною якого також є написання власної реалізації Applicative.
Автори:
Трансформери монад
Тестування, тести, специфікації, тестування властивостей та генеративне
-
Фантастичний посібник від Kazu Yamamoto.
-
Simple-Conduit: Гарна маленька бібліотека, яка допомогає зрозуміти, як загалом працює потоковий IO. Це знання можна відобразити на бібліотеки типу Pipes та Conduit.
Парсинг у Haskell
-
Посібник з комбінаторів парсеру із використанням Parsec
Парсинг та генерація JSON
Aeson - стандартне рішення для парсингу JSON в Haskell. Цей пакет доступний на hackage та github.
Структури даних та алгоритми для роботи з графами
-
Пакет fgl, зокрема чисто функціональні алгоритми найкоротшого шляху.
Середовище розробки
Emacs
Vim
Sublime Text
Робота із Cabal
Принципи роботи з Cabal
До того, як з'явились так звані сендбокси, користувачі Haskell стикались з проблемою, відомою як Cabal Hell. Встановлення пакетів поза сендбоксом призведе до реєстрації його у базі package-db, що є глобальною для користувача, і зазвичай це не дуже гарна ідея. Виключенням є лише найбазовіші пакети накшталт Cabal, alex, happy. Нічого іншого не мусить встановлюватись у package-db глобальний для системи або користувача окрім випадків, коли ви дійсно знаєте, що робите.
Поради як запобігти потраплянню в Cabal Hell, можна прочитати тут.
Для того, щоб поекспериментувати із пакетом, або розпочати новий проект, почніть зі створення сендбоксу у новій директорії: cabal sandbox init
.
Якщо коротко:
-
Завжди використовуйте сендбокси для інсталяції нових пакетів, збирання нових або існуючих проектів, або ж для експериментів.
-
Для запуску інтерпретатору GHC у контексті проекту, завжди використовуйте
cabal repl
.
Рекомендований тут підхід, що базується на використанні сендбоксів, призначений допомогти обійти проблеми із залежностями, але він не сумісний із тим, як Haskell Platform надає готові пакунки. Якщо ви ще тільки вивчаєте Haskell і не розумієте, як працють ghc-pkg and Cabal, уникайте platform і замість того використовуйте підхід, що описано раніше в цьому посібнику.
Stackage
Усі користувачі, в яких є проблеми з білдами (зазвичай це користувачі Yesod), мають можливість обміркувати використання Stackage.
- Непоганий огляд Stackage можна знайти тут.
Автор вважає, що Stackage, зазвичай, більш корисний, ніж cabal freeze
.
Hoogle and Haddock
Шукайте код за сигнатурою типів
Пошуковий сервіс Hoogle вміє шукати за типом.
Наприклад, подивіться на результати пошуку за виразом (a -> b) -> [a] -> [b]
тут.
Ще одне дзеркало на fpcomplete.
Ще є Hayoo (який для пошуку за замовченням використовує увесь зміст hackage).
Налаштування власної локальної копії Hoogle
Haddock
Зауваження: обидві статті трошки застаріли: наприклад, зараз Hackage також показує новесеньку інформацію стосовно статусу білда і документації.
Що дійсно треба знати
Для того, щоб haddocks містив документацію і з пакунків, які стосуються вашого проекту, треба додати documentation: True
до вашого ~/.cabal/config
. Якщо було використане значення за замовчуванням (False
) або False
було встановлене вручну, то перед генерацією haddocks необхідно буде видалити всі ваші пакунки і заново переінсталювати їх.
Треба пам'ятати ще одну річ: через те, що Cabal, а не ви, інтерпретує параметр $pkg
, параметри html-location
та content-location
мусять бути записані у одинарних лапках і введені в командний інтерпретатор або записані у скрипті інтерпретатора. Вони не будуть працювати у Makefile через те, що вони будуть інтерпретовані як змінні Make!
#! /usr/bin/env sh
# Цю команду можна записати в один рядок, але тоді приберіть слеші
cabal haddock --hoogle --hyperlink-source \
--html-location='http://hackage.haskell.org/package/$pkg/docs' \
--contents-location='http://hackage.haskell.org/package/$pkg'
TravisCI
Якщо ви є великим шанувальником TravisCI, тоді дуже рекомендується подивитись на multi-ghc-travis як на базовий приклад travis.yml
для ваших Haskell-проектів.
Frontend/JavaScript
Тут в нас є просто безліч різноманітних варіантів. Ось три базові рекомендації:
-
Haste компілятор із Haskell в Javascript
- Компілятор на github.
- Чудова демка використання Haste із реальним проектом.
-
- Доволі популярний вибір серед прибічників Haskell, хоча, на відміну від Haste та GHCJS, це не зовсім Haskell.
- Написано на Haskell під впливом Haskell
- Спробувати PureScript прямо у браузері можна тут
- Чудовий посібник про те, як почати працювати з PureScript
Яку мову використовувати для фронтенду
І GHCJS, і Haste є повноцінними реалізаціями Haskell. Під GHCJS будуть працювати більше Haskell проектів, ніж із Haste, але це не дуже впливає на розробку фронтенд-проектів. Purescript - це зовсім не Haskell і тому використовувати код із бекенду напряму не вийде.
GHCJS має найбільший розмір допоміжних бібліотек, необхідних для його роботи, який сягає 100Кб (luite працює над цією проблемою). Haste та PureScript більш-менш однакові.
Інтеграція із інструментарем JS найкраща в PureScript (використовується gulp/grunt/bower), в той час як GHCJS та Haste краще працює із інструментами Haskell (Cabal).
Усі три - чудовий вибір і підходять для більшості фронтендових проектів.
Для більш повного розуміння лінивості NF, WHNF
Дослідницькі папери про ліниве лямбда-числення
Паралелізм/конкаренсі
-
Parallel and Concurrent Programming in Haskell. Ця книга за авторством Саймона Мерлоу (Simon Marlow) є, мабуть, однією із найкращих книг про паралелізм та конкаренсі
-
Ґрунтовний посібник стосовно тестування та інкрементальної розробки багатопотокових програм на Haskell.
Lenses та Prisms
Після того, як ви набудете певності у роботі із Haskell, поставьтесь серйозно до вивчення Lenses та Prisms, навіть якщо ви просто "користувач". Для того, щоб вони стали вам у нагоді, не треба розуміти базові для них категорії.
Люди з легкістю переоцінюють складність використання Lens. Будь-хто із достатнім розумінням Functor/Foldable/Traversable (або навіть лише Functor) може використати лінзи та призми для того, щоб зробити своє життя трішечки краще.
Якщо коли небудь ви писали щось типу (fmap . fmap)
, ви подумки використовували лінзи.
Ці дві статті є рекомендованим введенням в тему:
Для подальшої інформації звертайтесь сюди: Lens package on hackage.
Схеми рекурсії
Деякі божевільні *-morphism слова, які ви зустрічали, насправді говорять про рекурсію. Зауважте: перед тим, як переходити до цього матеріалу, треба розуміти, як реалізувати foldr для списків і хочаб ще однієї структури даних, наприклад для дерев (fold - це катаморфізм). Розуміння реалізації unfold (анаморфізм) для тих же структур ще більше полегшить вивчення теми.
Цей матеріал пов'язує між собою traversable та foldable.
-
Don't fear the cat - Цікава демонстрація того, що гілеоморфізм є композицією катаморфізму та анаморфізму.
-
Recursion Schemes - Блискучий практичний досвід
-
Functional Programming with Bananas, Lenses, Envelopes and Barbed Wire
GHC Core та оптимізація швидкості виконання
Типи та теорія категорій
НЕ ПОТРІБНА для того, щоб просто писати на Haskell. Просто для тих, хто цікавиться.
Якщо ви маєте час та натхнення набути розуміння типів та теорії категорій:
-
Haskell wikibook містить непогані діаграми
-
Сторінка Category Theory у haskellwiki також містить чудові посилання на інші ресурси
-
Categories from scratch, містить також і практичні приклади.
-
Список Great Works in PL за авторством Пірса.
Книги
-
Quora Question: What is the best textbook for category theory? Рекомендація Кметта (Kmett)
-
Awodey та MacLane. Стандартні підручники з теорії категорій.
-
Harper's Practical Foundations for Programming Languages - найкраще введення у теорію типів із фокусом на мовах програмування.
Інші веселі теми
Параметричність, ad-hoc та параметричний поліморфізм, вільні теореми
-
TeX оригінали вищевказанної доповіді
Initial та Final, DSL, Finally Tagless
-
The dog that didn't bark менш релевантна, але все одно цікава стаття.
Комонади
Yoneda / CoYoneda
-
Free monads for Less, a sequence of three articles by Edward Kmett
Propositions vs. Judgments (обчислення)
Залежна типізація
Статична лінковка бінарників
Діалоги
Діалоги із IRC знаходяться в цьому документі.
Це дуже важлива та корисна інформація. Зазирніть туди щоб заглибитись у різноманітні теми.