Початок роботи з Haskell


755

Кілька днів я намагався обернути голову навколо парадигми функціонального програмування в Haskell. Я це робив, читаючи підручники і переглядаючи скріншоти, але насправді нічого, схоже, не тримається. Зараз, вивчаючи різні імперативні мови / мови OO (наприклад, C, Java, PHP), вправи були хорошим способом для мене. Але оскільки я не знаю, на що здатний Haskell, і тому що є багато нових концепцій, які можна використовувати, я не знав, з чого почати.

Отже, як ви навчилися Haskell? Що змусило вас насправді «зламати лід»? Також якісь хороші ідеї для початку вправ?


Відповіді:


2476

Я збираюся замовити цей довідник за рівнем майстерності, яку ви маєте в Haskell, переходячи від абсолютного початківця аж до експерта. Зауважте, що цей процес займе багато місяців (років?), Тому він досить тривалий.

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

По-перше, Haskell здатний на що завгодно, з достатньою майстерністю. Це дуже швидко (за моїм досвідом лише C і C ++), і його можна використовувати для будь-якого, від моделювання до серверів, guis та веб-додатків.

Однак є деякі проблеми, про які легше написати новачка в Haskell, ніж інші. Математичні проблеми та перелік програмних процесів є хорошими кандидатами для цього, оскільки для їх запису потрібні лише основні знання Haskell.

По-перше, кілька хороших посібників для вивчення самих основ Haskell - це навчальний посібник зі щасливим вивченням haskell та перші 6 глав, які вивчають вам haskell . Читаючи їх, дуже гарна ідея також вирішувати прості проблеми з тим, що ви знаєте.

Ще два хороших ресурси - програмування Haskell з перших принципів та програмування в Haskell . Вони обидва входять з вправами для кожної глави, тому у вас є невеликі прості проблеми, пов'язані з тим, що ви дізналися на останніх кількох сторінках.

Хороший список проблем, які слід спробувати, - це сторінка проблем haskell 99 . Вони починаються дуже елементарно, і стає складніше, як ви продовжуєте. Дуже добре, що багато таких роблять, оскільки вони дозволяють вам практикувати свої навички в рекурсії та функціях вищого порядку. Я рекомендую пропустити будь-які проблеми, які вимагають випадковості, оскільки це в Хаскеллі трохи складніше. Перевірте це питання ТАК, якщо ви хочете перевірити свої рішення за допомогою QuickCheck (див. Проміжний нижче).

Після того, як ви зробите декілька таких, ви можете перейти до виконання декількох проблем Project Euler . Вони сортуються за кількістю людей, які закінчили їх, що є досить хорошим показником складності. Вони перевіряють вашу логіку та Haskell більше, ніж попередні проблеми, але ви все одно зможете зробити перші кілька. Великою перевагою Haskell у цих проблемах є те, що цілі особи не обмежені в розмірі. Щоб виконати деякі з цих проблем, буде корисно прочитати глави 7 та 8, щоб дізнатись і про Haskell.

Новачок

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

Опрацювання проблем у книзі - це чудовий спосіб навчитися керувати абстракціями та будувати багаторазові компоненти в Haskell. Це важливо для людей, які використовуються для об'єктно-орієнтованого (oo) програмування, оскільки звичайні методи абстрагування oo (класи oo) не з'являються в Haskell (Haskell має типи класів, але вони сильно відрізняються від oo класів, більше схожі на oo інтерфейси ). Я не думаю, що пропускати глави не годиться, оскільки кожен представляє багато нових ідей, які використовуються в наступних главах.

Через деякий час ви перейдете до 14 глави, страшної глави монади (dum dum dummmm). Практично кожен, хто навчається Хаскеллу, має проблеми з розумінням монад, через те, наскільки поняття абстрактне. Я не можу придумати жодної концепції на іншій мові, яка є такою ж абстрактною, як монади у функціональному програмуванні. Monads дозволяє багато ідей (таких як операції вводу-виводу, обчислення, які можуть вийти з ладу, розбору, ...) бути об'єднані в одну ідею. Тому не відчувайте себе обезчереними, якщо після прочитання глави монад ви їх не дуже розумієте. Мені було корисно читати багато різних пояснень монад; кожен дає новий погляд на проблему. Ось дуже хороший список навчальних посібників з монади . Я настійно рекомендую все про монади , але інші також хороші.

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

Щоб переконатися, що ви прекрасно розумієте систему типу Haskell, вам слід спробувати вирішити 20 проміжних вправ haskell . Ці вправи, які використовують забавні назви таких функцій, як "пухнастий" та "банан", допомагають вам добре розуміти деякі основні концепції функціонального програмування, якщо ви їх ще не маєте. Хороший спосіб провести вечір за допомогою купки паперів, покритих стрілами, єдинорогів, сосисок та пухнастих бананів.

Проміжний

Після того, як ви зрозумієте Monads, я думаю, ви перейшли від початкового програміста Haskell до проміжного haskeller. То куди піти звідси? Перше, що я рекомендував би (якщо ви ще не навчилися їх вивчати монади) - це різні типи монад, такі як Reader, Writer та State. Знову ж таки, Реальний світ Хаскелл та Все про монади дає велике висвітлення цього. Щоб завершити навчання монаді, знання про трансформатори монади є обов'язковим. Вони дозволяють поєднувати різні типи Монад (наприклад, читацьку та державну монаду) в одну. Спочатку це може здатися марним, але, користуючись ними деякий час, ви будете замислюватися, як ви жили без них.

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

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

  • Парсек : для розбору програм та тексту. Набагато краще, ніж використання регулярних виразів. Відмінна документація, також має реальну главу Haskell.

  • QuickCheck : Дуже класна програма тестування. Що ви робите, - це написати присудок, який завжди повинен бути правдивим (наприклад length (reverse lst) == length lst). Потім ви передаєте предикат QuickCheck, і він генерує безліч випадкових значень (у цьому випадку списків) і перевіряє, що предикат відповідає всім результатам. Дивіться також онлайн-посібник .

  • HUnit : Тестування блоку в Haskell.

  • gtk2hs : найпопулярніший фреймворк gui для Haskell, дозволяє писати gtk програми в Haskell.

  • happystack : Структура веб-розробки для Haskell. Не використовує бази даних, а зберігає тип даних. Досить хороші документи (інші популярні рамки будуть хапати і Йесод ).

Крім того, існує багато понять (як, наприклад, концепція Монади), яких слід з часом вивчити. Це буде простіше, ніж вперше вивчити Монади, оскільки ваш мозок буде звик працювати з рівнем абстракції. Дуже хороший огляд для вивчення цих концепцій високого рівня та того, як вони поєднуються разом, є Typeclassopedia .

  • Додаток: Інтерфейс, як Monads, але менш потужний. Кожна Монада є додатковою, але не навпаки. Це корисно, оскільки є деякі типи, які є застосовними, але не є Монадами. Також код, написаний за допомогою функцій Applicative, часто є більш компонованим, ніж написання еквівалентного коду за допомогою функцій Monad. Дивіться про функціонерів, прикладних функціонерів та моноїдів у посібнику, що вивчає вам haskell.

  • Складаний , Traversable : Класи типів , що абстрактні багато з операцій списків, так що одні і ті ж функції можуть бути застосовані до інших типів контейнерів. Дивіться також пояснення вікі haskell .

  • Моноїд : Моноїд - це тип, який має нульове (або порожнє) значення та операцію, позначену, <>що з'єднує два моноїди разом, такі як x <> mempty = mempty <> x = xі x <> (y <> z) = (x <> y) <> z. Вони називаються законами тотожності та асоціативності. Багато типів - моноїди, такі як числа, з mempty = 0і <> = +. Це корисно у багатьох ситуаціях.

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

  • Масиви : різні змінні / незмінні масиви в Haskell.

  • ST Monad : дозволяє писати код із змінним станом, який працює дуже швидко, залишаючись чистим поза монадою. Детальніше див. За посиланням.

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

Є багато нових мовних особливостей, на які слід звернути увагу. Я просто перерахую їх, ви можете знайти багато інформації про них з google, wikibook haskell , сайту haskellwiki.org та документації ghc .

  • Класи багатопараметричних типів / функціональні залежності
  • Тип сімей
  • Екзистенційно кількісні типи
  • Фантомні типи
  • ГАДЦІ
  • інші ...

Багато теорій Хаскелла базується на теорії категорій , тож ви можете розглянути це. Хорошим початковим пунктом є теорія категорії для вчених-комп'ютерів . Якщо ви не хочете купувати книгу, стаття , що стосується автора, також чудова.

Нарешті ви захочете дізнатися більше про різні інструменти Haskell. До них належать:

  • ghc (та всі його особливості)
  • кабал : система пакетів Haskell
  • darcs : розподілена система контролю версій, написана в Haskell, дуже популярна для програм Haskell.
  • пикша : автоматичний генератор документації Haskell

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

Експерт

На цю стадію знадобляться роки (привіт з 2009 року!), Але звідси я здогадуюсь, що ти починаєш писати Phd документи, нові розширення ghc та придумуєш нові абстракції.

Отримання довідки

Нарешті, на будь-якому етапі навчання є багато місць для отримання інформації. Це:

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

Висновок

Ну це вийшло довше, ніж я очікував ... У будь-якому випадку, я думаю, що це дуже гарна ідея стати фахівцем в Haskell. Це займає багато часу, але це головним чином тому, що ви вчитеся абсолютно новому мисленню, роблячи це. Це не як навчання Ruby після вивчення Java, а як вивчення Java після вивчення C. Також я знаходжу, що мої навички об'єктно-орієнтованого програмування покращилися в результаті вивчення Haskell, оскільки я бачу багато нових способів абстрагування ідей.


35
Так стрілки! Спочатку ви даєте монадам формувати ваш мозок, потім ви стоїте на голові і думаєте про коонади, а потім ви робите обидва одночасно, щоб отримати стрілки :) У Haskell є багато виразної сили, яку можна відкрити на рівні типу програмування теж.
ефемія

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

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

2
Чудова порада. Я розпочав це понад рік тому, і проходжу більшу частину шляху через проміжний етап. Зворотній зв'язок: глава монади RWH (глава 14) пояснюється недостатньо. Читання онлайн-версії RWH є вигідним, оскільки містить зауваження, що містять багато джерел, які допомагають главі. FWIW, Ви могли придумати монади , був монадіальним підручником, який найкраще працював для мене.
Том

6
@tomf: Дякую! Мене завжди дивувало, наскільки добре ця відповідь виконана - минуло майже п'ять років, як я її написав, але вона все ще сильна. Мені незабаром потрібно буде оновити його, оскільки воно трохи застаріло. Тут не згадуються лінзи, труби, види обмежень, платформа haskell, номери рівня типу, і вони є досить новими новими темами, оскільки це було написано. Ви праві, що RWH вже не так добре, він не оновлювався давно, і багато прикладів не складаються. Я радий, що все одно тобі було корисно.
Девід Міані

179

Хтось із моїх колег мав хороший досвід з Learn You a Haskell for Great Good! .

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

І перевірити відповіді тут теж


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

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

7
Я абсолютно люблю це, і я вклав багато часу в цей і реальний світ Haskell. IMO, "Learn You a Haskell" дає глибший огляд, ніж Haskell Real World, хоча вони обидва чудові ресурси.
Charlie Flowers

7
@ abababa22 Я думаю, що спочатку прочитати LYAH, а потім перейти до RWH - найкраща ідея. ЛЯХ не вчить вас просто Хаскеллу; він навчає функціонального програмування. Ви починаєте функціонально мислити, коли вирішуєте проблеми. Зрозуміло, що лише LYAH було б недостатньо, щоб написати велику заявку, але це нахиляє розум правильно. Якщо ви перебуваєте в обов'язковому порядку, це найкращий спосіб, IMO
Абдулсаттар Мухаммед

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

103

Ось хороша книга, яку ви можете прочитати в Інтернеті: Реальний світ Хаскелл

Більшість програм Haskell, які я робив, стосувалися вирішення проблем Project Euler .

Колись порада, яку я прочитав не так давно, - це те, що у вас повинен бути стандартний набір простих проблем, які ви знаєте, як їх вирішити (теоретично), а потім, коли ви намагаєтесь вивчити нову мову, ви реалізуєте ці проблеми на цій мові.


2
На мій досвід Haskell в реальному світі чудовий, доки ви не досягнете глави 5. З цього моменту я б не рекомендував його.
MasterMastic

Чому @MasterMastic? Яка проблема є поза главою 5? Я хотів би знати, перш ніж витратити гроші.
Джей Бланшард

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


69

Щоб додати відповіді інших - є одна корисна, яка допоможе вам при кодуванні (наприклад, при вирішенні проблем проекту Euler): 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 про те, що вам потрібно.
ankh-morpork

57

Програмування Грема Хаттона в Haskell є стислим, досить ретельним, і його роки викладання Haskell дійсно показують. Я майже завжди рекомендую людям починати, незалежно від того, звідки ви їдете.

Зокрема, Глава 8 ("Функціональні парсери") дає реальну основу, необхідну для початку роботи з монадами, і, на мою думку, це далеко не найкраще місце для початку, після якого йде " Все про монади" . (Однак, що стосується цієї глави, зауважте помилки на веб-сайті: однак ви не можете скористатися doформою без спеціальної допомоги. Можливо, спочатку ви хочете дізнатися про машинокласи та вирішити цю проблему самостійно.)

Це рідко підкреслюється для початківців Haskell, але варто навчитися досить рано не просто використовувати монади, а й побудувати свій власний. Це не важко, і на замовлення вони можуть зробити ряд завдань більш простими.


5
Це зовсім недооцінена книга (і відповідь). Глава про функціональні парсери, за якою слідує глава про ІО, жодна з яких навіть не згадує про монади, справді світить як елегантний педагогічний підхід.
michiakig

52

Не намагайтеся читати всі підручники з монади із кумедними метафорами. Вони просто змусять вас заплутатися ще гірше.


5
Домовились! Див. "Абстракція, інтуїція та" помилка підручника монади ": byorgey.wordpress.com/2009/01/12/…
ShreevatsaR

31

Я б запропонував приєднатися до каналу #haskell irc і задати там питання. Ось як я дізнався Хаскелл. Якщо ви проходите Haskell в реальному світі, як було запропоновано вище, відповіді на ваші запитання в реальному часі дуже допоможуть. Багато розумних людей на #haskell пишуть Haskell для розваги та для отримання прибутку, тому ви отримаєте багато хорошого вкладу. Спробуй це!


5
+1 - Щоб зрозуміти: не вчіть це лише за допомогою каналу irc. Як і в, не заходьте і запитайте "Як написати програму haskell? Як додати цифри?"
альтернатива

Окрім irc freenode, останнім часом також спостерігається посилення жвавої дискусії щодо haskell в чатах Discord.
шрифт


19

Я можу додатково порекомендувати ще один підручник з Haskell як вступ.

Ще один хороший навчальний ресурс (напевно, на проміжному рівні), який мені дуже допоміг і не згадується в інших відповідях, наскільки я можу бачити, - це Typeclassopedia Брента Йоргея , яку можна знайти в The Monad Reader (Issue 13)

Він написаний дуже доступним стилем і містить (серед іншого) наступні вступні поради:

Існує два ключі до мудрості хакельського експерта:

  1. Зрозумійте типи.

  2. Набути глибокої інтуїції для кожного класу типу та його відношення до інших класів типів, підкріплених знайомством з багатьма прикладами.

Читач Monad сам по собі є абсолютною скарбницею функціональних програмістів (не тільки програмістів Haskell).


14

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

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

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

Після того, як я вирішив десяток, я зламав лід :)

Після цього читайте багато про вдосконалені поняття (Monads, Arrow, 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 в майбутньому.

це мій найкращий спосіб вивчення haskell. Я сподіваюся, що це може вам допомогти.


13

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

Навчальний посібник БОНУС стане вашим першочерговим і підготується до гострої їзди, яку приносить Real World Haskell. Нехай щастить!


12

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


В'яз може бути найближчим, більш корисним і сприйняттям початківців з цих альтернатив ...
Педро Роло

1
Я не згоден у проходженні через тимчасовий маршрут, як F #. Для мене це як пити горілку, її потрібно швидко попивати. Більш болісно, ​​але задоволення теж є. Тимчасові маршрути, лише призводять до більшої плутанини для мене.
шрифт

10

Перша відповідь дуже хороша. Для того, щоб досягти рівня Експертів, вам слід зробити докторську ступінь з деякими експертами.

Я пропоную вам відвідати сторінку Haskell: http://haskell.org . Там у вас є багато матеріалу та багато посилань на найновіші речі в Haskell, затверджені громадою Haskell.


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