<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="uk">
	<id>https://wiki.erp.kyiv.ua/index.php?action=history&amp;feed=atom&amp;title=Haskell</id>
	<title>Haskell - Історія редагувань</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.erp.kyiv.ua/index.php?action=history&amp;feed=atom&amp;title=Haskell"/>
	<link rel="alternate" type="text/html" href="https://wiki.erp.kyiv.ua/index.php?title=Haskell&amp;action=history"/>
	<updated>2026-05-10T07:06:49Z</updated>
	<subtitle>Історія редагувань цієї сторінки в вікі</subtitle>
	<generator>MediaWiki 1.45.3</generator>
	<entry>
		<id>https://wiki.erp.kyiv.ua/index.php?title=Haskell&amp;diff=1286&amp;oldid=prev</id>
		<title>R в 20:35, 8 травня 2026</title>
		<link rel="alternate" type="text/html" href="https://wiki.erp.kyiv.ua/index.php?title=Haskell&amp;diff=1286&amp;oldid=prev"/>
		<updated>2026-05-08T20:35:10Z</updated>

		<summary type="html">&lt;p&gt;&lt;/p&gt;
&lt;a href=&quot;https://wiki.erp.kyiv.ua/index.php?title=Haskell&amp;amp;diff=1286&amp;amp;oldid=1284&quot;&gt;Показати зміни&lt;/a&gt;</summary>
		<author><name>R</name></author>
	</entry>
	<entry>
		<id>https://wiki.erp.kyiv.ua/index.php?title=Haskell&amp;diff=1284&amp;oldid=prev</id>
		<title>R: Створена сторінка: {{SEO|title=Haskell — функціональна мова програмування, чисті функції, типи, монади, lazy evaluation, GHC, Cabal, Stack і безпечна архітектура|description=Haskell — Wiki-стаття про чисту функціональну мову програмування Haskell. Розглянуто pure functions, immutability, lazy evaluation, referential transparency, algebraic data ty...</title>
		<link rel="alternate" type="text/html" href="https://wiki.erp.kyiv.ua/index.php?title=Haskell&amp;diff=1284&amp;oldid=prev"/>
		<updated>2026-05-08T20:29:09Z</updated>

		<summary type="html">&lt;p&gt;Створена сторінка: {{SEO|title=Haskell — функціональна мова програмування, чисті функції, типи, монади, lazy evaluation, GHC, Cabal, Stack і безпечна архітектура|description=Haskell — Wiki-стаття про чисту функціональну мову програмування Haskell. Розглянуто pure functions, immutability, lazy evaluation, referential transparency, algebraic data ty...&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Нова сторінка&lt;/b&gt;&lt;/p&gt;&lt;div&gt;{{SEO|title=Haskell — функціональна мова програмування, чисті функції, типи, монади, lazy evaluation, GHC, Cabal, Stack і безпечна архітектура|description=Haskell — Wiki-стаття про чисту функціональну мову програмування Haskell. Розглянуто pure functions, immutability, lazy evaluation, referential transparency, algebraic data types, pattern matching, type classes, monads, functors, applicatives, GHC, GHCi, Cabal, Stack, GHCup, Haskell Language Server, Hackage, Stackage, тестування, QuickCheck, property-based testing, web/backend, компіляцію, продуктивність, обмеження, практичне використання та місце Haskell у сучасній розробці.|keywords=Haskell, функціональне програмування, functional programming, pure functions, immutability, lazy evaluation, referential transparency, algebraic data types, pattern matching, type classes, monads, functor, applicative, GHC, GHC 9.14, GHC 9.12, Cabal, Stack, GHCup, Haskell Language Server, Hackage, Stackage, QuickCheck, property based testing, Haskell backend, Haskell web, typed functional programming, програмування Haskell|alternativeTo=імперативне програмування зі станом всюди; runtime-помилки через слабку типізацію; бізнес-логіка без математичної моделі; код без referential transparency; складні side effects без контролю; тестування лише прикладами без property-based testing; архітектура без сильних типів; обробка помилок через неявні exceptions}}&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Haskell&amp;#039;&amp;#039;&amp;#039; — це чиста функціональна мова програмування зі статичною типізацією, lazy evaluation, immutable data, algebraic data types, pattern matching, type classes і сильним акцентом на математичну коректність програм.&lt;br /&gt;
&lt;br /&gt;
Haskell часто використовують для навчання функціональному мисленню, компіляторів, формальних моделей, financial systems, backend-сервісів, DSL, research, high-assurance code, parserів, складної бізнес-логіки й задач, де типи можуть запобігти великій кількості помилок.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;background:#eef6ff;border-left:6px solid #2f80ed;padding:14px 18px;margin:16px 0;border-radius:8px;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Коротко:&amp;#039;&amp;#039;&amp;#039; Haskell — це мова, де функції чисті, дані immutable, типи дуже сильні, а side effects явно контролюються. Вона вимагає іншого мислення, але допомагає писати дуже передбачуваний код.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Офіційна сторінка Haskell описує мову як purely functional programming language із referential transparency, immutability і lazy evaluation. &amp;lt;ref&amp;gt;https://www.haskell.org/&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Головна ідея ==&lt;br /&gt;
&lt;br /&gt;
Головна ідея Haskell — будувати програми як композицію чистих функцій і точно описаних типів.&lt;br /&gt;
&lt;br /&gt;
У звичайному імперативному стилі програма часто змінює стан:&lt;br /&gt;
&lt;br /&gt;
* змінні перезаписуються;&lt;br /&gt;
* об’єкти мутують;&lt;br /&gt;
* функції можуть змінювати глобальні дані;&lt;br /&gt;
* side effects приховані;&lt;br /&gt;
* порядок виконання дуже важливий.&lt;br /&gt;
&lt;br /&gt;
У Haskell підхід інший:&lt;br /&gt;
&lt;br /&gt;
* значення immutable;&lt;br /&gt;
* функції не змінюють світ без явного типу;&lt;br /&gt;
* типи описують можливі стани;&lt;br /&gt;
* багато помилок ловить компілятор;&lt;br /&gt;
* програма будується через композицію функцій.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;background:#f6ffed;border-left:6px solid #27ae60;padding:14px 18px;margin:16px 0;border-radius:8px;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Проста аналогія:&amp;#039;&amp;#039;&amp;#039; Haskell змушує спочатку чітко описати “які значення можливі”, а вже потім писати код. Це схоже на креслення перед будівництвом, а не ремонт під час руху.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Актуальний стан інструментів ==&lt;br /&gt;
&lt;br /&gt;
Станом на травень 2026 року офіційна сторінка GHC показує серед останніх релізів &amp;#039;&amp;#039;&amp;#039;GHC 9.12.4&amp;#039;&amp;#039;&amp;#039; від 27 березня 2026 року і &amp;#039;&amp;#039;&amp;#039;GHC 9.14.1&amp;#039;&amp;#039;&amp;#039; від 19 грудня 2025 року. &amp;lt;ref&amp;gt;https://www.haskell.org/ghc/&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Офіційна сторінка Haskell Downloads рекомендує встановлювати Haskell через &amp;#039;&amp;#039;&amp;#039;GHCup&amp;#039;&amp;#039;&amp;#039;, який може встановити GHC, cabal-install, Stack і Haskell Language Server. &amp;lt;ref&amp;gt;https://www.haskell.org/downloads/&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
GHC також запровадив LTS-підхід: Haskell.org повідомляв, що GHC починає підтримувати LTS release/branch із довшим періодом підтримки, орієнтовно від двох до трьох років. &amp;lt;ref&amp;gt;https://www.haskell.org/ghc/blog/20250702-ghc-release-schedules.html&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;background:#fff7e6;border-left:6px solid #f2994a;padding:14px 18px;margin:16px 0;border-radius:8px;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Для документації:&amp;#039;&amp;#039;&amp;#039; у Haskell-проєктах важливо фіксувати версії GHC, Cabal/Stack і package set. Різні версії compiler і dependencies можуть суттєво впливати на build.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== GHC ==&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;GHC&amp;#039;&amp;#039;&amp;#039; або &amp;#039;&amp;#039;&amp;#039;Glasgow Haskell Compiler&amp;#039;&amp;#039;&amp;#039; — головний компілятор Haskell.&lt;br /&gt;
&lt;br /&gt;
GHC включає:&lt;br /&gt;
&lt;br /&gt;
* compiler;&lt;br /&gt;
* runtime system;&lt;br /&gt;
* GHCi;&lt;br /&gt;
* optimizer;&lt;br /&gt;
* extensions;&lt;br /&gt;
* profiling support;&lt;br /&gt;
* documentation;&lt;br /&gt;
* libraries;&lt;br /&gt;
* package support.&lt;br /&gt;
&lt;br /&gt;
GHC є фактичним стандартом для сучасного Haskell.&lt;br /&gt;
&lt;br /&gt;
Офіційна сторінка GHC описує його як state-of-the-art open source compiler and interactive environment for Haskell. &amp;lt;ref&amp;gt;https://www.haskell.org/ghc/&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== GHCi ==&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;GHCi&amp;#039;&amp;#039;&amp;#039; — інтерактивне середовище Haskell.&lt;br /&gt;
&lt;br /&gt;
Приклад:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ghci&lt;br /&gt;
Prelude&amp;gt; 2 + 3&lt;br /&gt;
5&lt;br /&gt;
Prelude&amp;gt; map (*2) [1,2,3]&lt;br /&gt;
[2,4,6]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
GHCi корисний для:&lt;br /&gt;
&lt;br /&gt;
* навчання;&lt;br /&gt;
* швидкої перевірки functions;&lt;br /&gt;
* type exploration;&lt;br /&gt;
* debugging;&lt;br /&gt;
* prototyping;&lt;br /&gt;
* REPL workflow.&lt;br /&gt;
&lt;br /&gt;
== GHCup ==&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;GHCup&amp;#039;&amp;#039;&amp;#039; — рекомендований installer і manager для Haskell toolchain.&lt;br /&gt;
&lt;br /&gt;
Через GHCup можна встановлювати:&lt;br /&gt;
&lt;br /&gt;
* GHC;&lt;br /&gt;
* cabal-install;&lt;br /&gt;
* Stack;&lt;br /&gt;
* Haskell Language Server.&lt;br /&gt;
&lt;br /&gt;
Офіційна сторінка Haskell Downloads прямо рекомендує GHCup для Linux, macOS, FreeBSD, Windows або WSL2. &amp;lt;ref&amp;gt;https://www.haskell.org/downloads/&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Cabal ==&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Cabal&amp;#039;&amp;#039;&amp;#039; — build system і package description format для Haskell.&lt;br /&gt;
&lt;br /&gt;
Cabal використовується для:&lt;br /&gt;
&lt;br /&gt;
* опису packages;&lt;br /&gt;
* builds;&lt;br /&gt;
* dependencies;&lt;br /&gt;
* tests;&lt;br /&gt;
* benchmarks;&lt;br /&gt;
* library/executable targets;&lt;br /&gt;
* Hackage packages.&lt;br /&gt;
&lt;br /&gt;
Типові команди:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cabal update&lt;br /&gt;
cabal build&lt;br /&gt;
cabal test&lt;br /&gt;
cabal run&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Haskell documentation page містить Cabal User Guide серед основних довідників Haskell tooling. &amp;lt;ref&amp;gt;https://www.haskell.org/documentation/&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Stack ==&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Stack&amp;#039;&amp;#039;&amp;#039; — альтернативний build tool для Haskell.&lt;br /&gt;
&lt;br /&gt;
Stack фокусується на reproducible builds і curated package sets через Stackage.&lt;br /&gt;
&lt;br /&gt;
Документація Stack описує, що Stack керує GHC installations і автоматично вибирає потрібну версію GHC для проєкту. &amp;lt;ref&amp;gt;https://docs.haskellstack.org/en/stable/&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Типові команди:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
stack new my-project&lt;br /&gt;
stack build&lt;br /&gt;
stack test&lt;br /&gt;
stack run&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Haskell Language Server ==&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Haskell Language Server&amp;#039;&amp;#039;&amp;#039; або &amp;#039;&amp;#039;&amp;#039;HLS&amp;#039;&amp;#039;&amp;#039; — language server для редакторів.&lt;br /&gt;
&lt;br /&gt;
Він дає:&lt;br /&gt;
&lt;br /&gt;
* автодоповнення;&lt;br /&gt;
* diagnostics;&lt;br /&gt;
* go to definition;&lt;br /&gt;
* hover info;&lt;br /&gt;
* code actions;&lt;br /&gt;
* formatting;&lt;br /&gt;
* type information;&lt;br /&gt;
* інтеграцію з VS Code, Vim, Emacs та іншими редакторами.&lt;br /&gt;
&lt;br /&gt;
Haskell Language Server releases підтримують конкретні версії GHC, тому сумісність HLS і GHC потрібно перевіряти. &amp;lt;ref&amp;gt;https://github.com/haskell/haskell-language-server/releases&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Hackage ==&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Hackage&amp;#039;&amp;#039;&amp;#039; — центральний repository Haskell packages.&lt;br /&gt;
&lt;br /&gt;
Там публікуються libraries і tools.&lt;br /&gt;
&lt;br /&gt;
Hackage корисний для:&lt;br /&gt;
&lt;br /&gt;
* пошуку libraries;&lt;br /&gt;
* перегляду package documentation;&lt;br /&gt;
* version history;&lt;br /&gt;
* dependencies;&lt;br /&gt;
* maintainers;&lt;br /&gt;
* source tarballs.&lt;br /&gt;
&lt;br /&gt;
Перед використанням package варто перевіряти maintenance, compatibility, license і recent releases.&lt;br /&gt;
&lt;br /&gt;
== Stackage ==&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Stackage&amp;#039;&amp;#039;&amp;#039; — curated package set для Haskell.&lt;br /&gt;
&lt;br /&gt;
Ідея Stackage — мати набір package versions, які разом проходять build.&lt;br /&gt;
&lt;br /&gt;
Це допомагає зменшити dependency conflicts.&lt;br /&gt;
&lt;br /&gt;
Stackage має:&lt;br /&gt;
&lt;br /&gt;
* LTS snapshots;&lt;br /&gt;
* nightly snapshots;&lt;br /&gt;
* GHC version binding;&lt;br /&gt;
* curated ecosystem.&lt;br /&gt;
&lt;br /&gt;
Наприклад, Stackage Nightly 2026-05-06 використовував GHC 9.12.4. &amp;lt;ref&amp;gt;https://www.stackage.org/nightly-2026-05-06&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Чиста функція ==&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Чиста функція&amp;#039;&amp;#039;&amp;#039; — функція, яка:&lt;br /&gt;
&lt;br /&gt;
* для однакових inputs завжди повертає однаковий output;&lt;br /&gt;
* не змінює зовнішній стан;&lt;br /&gt;
* не має прихованих side effects.&lt;br /&gt;
&lt;br /&gt;
Приклад:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
add :: Int -&amp;gt; Int -&amp;gt; Int&lt;br /&gt;
add a b = a + b&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ця функція чиста: вона лише обчислює суму.&lt;br /&gt;
&lt;br /&gt;
== Referential transparency ==&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Referential transparency&amp;#039;&amp;#039;&amp;#039; означає, що expression можна замінити його значенням без зміни поведінки програми.&lt;br /&gt;
&lt;br /&gt;
Наприклад:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
add 2 3&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
можна замінити на:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
5&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Це робить код передбачуванішим і полегшує reasoning.&lt;br /&gt;
&lt;br /&gt;
Офіційна сторінка Haskell називає referential transparency однією з ключових властивостей мови. &amp;lt;ref&amp;gt;https://www.haskell.org/&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Immutability ==&lt;br /&gt;
&lt;br /&gt;
У Haskell значення immutable за замовчуванням.&lt;br /&gt;
&lt;br /&gt;
Приклад:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
x = 10&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Це не змінна у звичному імперативному сенсі. Це binding імені &amp;lt;code&amp;gt;x&amp;lt;/code&amp;gt; до значення &amp;lt;code&amp;gt;10&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Immutability допомагає:&lt;br /&gt;
&lt;br /&gt;
* уникати випадкової зміни стану;&lt;br /&gt;
* спрощувати reasoning;&lt;br /&gt;
* краще працювати з concurrency;&lt;br /&gt;
* зменшувати кількість bugs.&lt;br /&gt;
&lt;br /&gt;
== Lazy evaluation ==&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Lazy evaluation&amp;#039;&amp;#039;&amp;#039; означає, що вирази обчислюються не одразу, а коли результат справді потрібен.&lt;br /&gt;
&lt;br /&gt;
Приклад:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
take 5 [1..]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
У Haskell це працює: нескінченний список &amp;lt;code&amp;gt;[1..]&amp;lt;/code&amp;gt; не обчислюється повністю. Беруться лише перші 5 елементів.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;background:#eef6ff;border-left:6px solid #2f80ed;padding:14px 18px;margin:16px 0;border-radius:8px;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Цікаво:&amp;#039;&amp;#039;&amp;#039; lazy evaluation дозволяє працювати з потенційно нескінченними структурами. Але вона також може створювати performance surprises, якщо не розуміти, коли саме обчислюються значення.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Strictness ==&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Strictness&amp;#039;&amp;#039;&amp;#039; — протилежний підхід до lazy evaluation: значення обчислюється раніше.&lt;br /&gt;
&lt;br /&gt;
У Haskell іноді потрібно явно керувати strictness, щоб уникнути:&lt;br /&gt;
&lt;br /&gt;
* memory leaks;&lt;br /&gt;
* накопичення thunks;&lt;br /&gt;
* неочікуваного використання пам’яті;&lt;br /&gt;
* performance problems.&lt;br /&gt;
&lt;br /&gt;
Для цього використовують:&lt;br /&gt;
&lt;br /&gt;
* bang patterns;&lt;br /&gt;
* seq;&lt;br /&gt;
* strict data fields;&lt;br /&gt;
* strict libraries;&lt;br /&gt;
* profiling.&lt;br /&gt;
&lt;br /&gt;
== Thunk ==&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Thunk&amp;#039;&amp;#039;&amp;#039; — відкладене обчислення.&lt;br /&gt;
&lt;br /&gt;
Через lazy evaluation Haskell може створювати thunks замість негайного обчислення значень.&lt;br /&gt;
&lt;br /&gt;
Це корисно для laziness, але якщо thunks накопичуються, може зрости використання пам’яті.&lt;br /&gt;
&lt;br /&gt;
== Типи ==&lt;br /&gt;
&lt;br /&gt;
Haskell має сильну статичну типізацію.&lt;br /&gt;
&lt;br /&gt;
Приклад:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
name :: String&lt;br /&gt;
name = &amp;quot;Haskell&amp;quot;&lt;br /&gt;
&lt;br /&gt;
count :: Int&lt;br /&gt;
count = 10&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Типи допомагають:&lt;br /&gt;
&lt;br /&gt;
* ловити помилки під час компіляції;&lt;br /&gt;
* документувати наміри;&lt;br /&gt;
* моделювати domain;&lt;br /&gt;
* забороняти неможливі стани;&lt;br /&gt;
* робити refactoring безпечнішим.&lt;br /&gt;
&lt;br /&gt;
== Type inference ==&lt;br /&gt;
&lt;br /&gt;
Haskell має потужний type inference.&lt;br /&gt;
&lt;br /&gt;
Можна написати:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
double x = x * 2&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
GHC сам виведе тип.&lt;br /&gt;
&lt;br /&gt;
Але в production-коді часто корисно писати type signatures:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
double :: Num a =&amp;gt; a -&amp;gt; a&lt;br /&gt;
double x = x * 2&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Type signatures документують код і допомагають ловити помилки раніше.&lt;br /&gt;
&lt;br /&gt;
== Algebraic Data Types ==&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Algebraic Data Types&amp;#039;&amp;#039;&amp;#039; або &amp;#039;&amp;#039;&amp;#039;ADT&amp;#039;&amp;#039;&amp;#039; — один із найсильніших інструментів Haskell.&lt;br /&gt;
&lt;br /&gt;
Приклад:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
data OrderStatus&lt;br /&gt;
  = Draft&lt;br /&gt;
  | Paid&lt;br /&gt;
  | Cancelled&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Це означає: статус замовлення може бути тільки Draft, Paid або Cancelled.&lt;br /&gt;
&lt;br /&gt;
ADT допомагають явно описувати domain states.&lt;br /&gt;
&lt;br /&gt;
== Product types і sum types ==&lt;br /&gt;
&lt;br /&gt;
Product type містить кілька полів.&lt;br /&gt;
&lt;br /&gt;
Приклад:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
data Customer = Customer&lt;br /&gt;
  { customerId :: Int&lt;br /&gt;
  , customerName :: String&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sum type описує вибір між варіантами.&lt;br /&gt;
&lt;br /&gt;
Приклад:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
data PaymentResult&lt;br /&gt;
  = PaymentOk&lt;br /&gt;
  | PaymentDeclined String&lt;br /&gt;
  | PaymentError String&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sum types дозволяють моделювати бізнес-логіку без неявних null або magic strings.&lt;br /&gt;
&lt;br /&gt;
== Pattern matching ==&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Pattern matching&amp;#039;&amp;#039;&amp;#039; — спосіб розібрати значення за формою.&lt;br /&gt;
&lt;br /&gt;
Приклад:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
statusText :: OrderStatus -&amp;gt; String&lt;br /&gt;
statusText Draft = &amp;quot;Чернетка&amp;quot;&lt;br /&gt;
statusText Paid = &amp;quot;Оплачено&amp;quot;&lt;br /&gt;
statusText Cancelled = &amp;quot;Скасовано&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Pattern matching робить код дуже читабельним для обробки ADT.&lt;br /&gt;
&lt;br /&gt;
== Guards ==&lt;br /&gt;
&lt;br /&gt;
Guards дозволяють писати умовну логіку.&lt;br /&gt;
&lt;br /&gt;
Приклад:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
discount :: Int -&amp;gt; Int&lt;br /&gt;
discount amount&lt;br /&gt;
  | amount &amp;gt; 10000 = 20&lt;br /&gt;
  | amount &amp;gt; 5000  = 10&lt;br /&gt;
  | otherwise      = 0&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Guards часто роблять код чистішим, ніж nested if.&lt;br /&gt;
&lt;br /&gt;
== Maybe ==&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Maybe&amp;#039;&amp;#039;&amp;#039; — тип для значення, яке може бути відсутнім.&lt;br /&gt;
&lt;br /&gt;
Приклад:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
data Maybe a = Nothing | Just a&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Практичне використання:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
findCustomer :: Int -&amp;gt; Maybe Customer&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Це означає: customer може бути знайдений або ні.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;background:#f6ffed;border-left:6px solid #27ae60;padding:14px 18px;margin:16px 0;border-radius:8px;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Практична користь:&amp;#039;&amp;#039;&amp;#039; замість null Haskell використовує тип &amp;lt;code&amp;gt;Maybe&amp;lt;/code&amp;gt;. Компілятор змушує вас обробити випадок, коли значення немає.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Either ==&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Either&amp;#039;&amp;#039;&amp;#039; часто використовується для результату з помилкою.&lt;br /&gt;
&lt;br /&gt;
Приклад:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
parseAmount :: String -&amp;gt; Either String Int&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Це означає:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;Right Int&amp;lt;/code&amp;gt; — успішний результат;&lt;br /&gt;
* &amp;lt;code&amp;gt;Left String&amp;lt;/code&amp;gt; — помилка.&lt;br /&gt;
&lt;br /&gt;
Either корисний для validation, parsing, API responses і business rules.&lt;br /&gt;
&lt;br /&gt;
== Type classes ==&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Type class&amp;#039;&amp;#039;&amp;#039; — механізм ad-hoc polymorphism.&lt;br /&gt;
&lt;br /&gt;
Приклад:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class Printable a where&lt;br /&gt;
  printValue :: a -&amp;gt; String&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Тип може мати instance:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
instance Printable Customer where&lt;br /&gt;
  printValue customer = customerName customer&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Type classes схожі на interfaces, але мають іншу семантику й велику роль у Haskell ecosystem.&lt;br /&gt;
&lt;br /&gt;
== Eq, Ord, Show, Read ==&lt;br /&gt;
&lt;br /&gt;
Базові type classes:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;Eq&amp;lt;/code&amp;gt; — порівняння на рівність;&lt;br /&gt;
* &amp;lt;code&amp;gt;Ord&amp;lt;/code&amp;gt; — порядок;&lt;br /&gt;
* &amp;lt;code&amp;gt;Show&amp;lt;/code&amp;gt; — перетворення в рядок;&lt;br /&gt;
* &amp;lt;code&amp;gt;Read&amp;lt;/code&amp;gt; — читання з рядка.&lt;br /&gt;
&lt;br /&gt;
Приклад:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
data Status = Draft | Paid&lt;br /&gt;
  deriving (Eq, Show)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;deriving&amp;lt;/code&amp;gt; автоматично створює instances.&lt;br /&gt;
&lt;br /&gt;
== Functor ==&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Functor&amp;#039;&amp;#039;&amp;#039; — type class для контейнерів або контекстів, над якими можна застосувати функцію.&lt;br /&gt;
&lt;br /&gt;
Ключова функція:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
fmap :: Functor f =&amp;gt; (a -&amp;gt; b) -&amp;gt; f a -&amp;gt; f b&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Приклад:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
fmap (+1) (Just 10)&lt;br /&gt;
-- Just 11&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Functor дозволяє працювати з “значенням у контексті”, не витягуючи його вручну.&lt;br /&gt;
&lt;br /&gt;
== Applicative ==&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Applicative&amp;#039;&amp;#039;&amp;#039; — abstraction між Functor і Monad.&lt;br /&gt;
&lt;br /&gt;
Вона дозволяє застосовувати function у контексті до value у контексті.&lt;br /&gt;
&lt;br /&gt;
Приклад ідеї:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
pure (+) &amp;lt;*&amp;gt; Just 2 &amp;lt;*&amp;gt; Just 3&lt;br /&gt;
-- Just 5&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Applicative часто використовують у validation, parsing і configuration.&lt;br /&gt;
&lt;br /&gt;
== Monad ==&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Monad&amp;#039;&amp;#039;&amp;#039; — abstraction для послідовного поєднання обчислень у контексті.&lt;br /&gt;
&lt;br /&gt;
Ключова ідея: результат одного кроку впливає на наступний крок.&lt;br /&gt;
&lt;br /&gt;
Приклад із Maybe:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
findCustomer customerId &amp;gt;&amp;gt;= findPrimaryEmail&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Якщо customer не знайдено, наступний крок не виконується.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;background:#fff7e6;border-left:6px solid #f2994a;padding:14px 18px;margin:16px 0;border-radius:8px;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Без містики:&amp;#039;&amp;#039;&amp;#039; монада — це не “магія”. Це спосіб акуратно з’єднувати обчислення, які мають контекст: Maybe, Either, IO, список, state, parser тощо.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== IO Monad ==&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;IO&amp;#039;&amp;#039;&amp;#039; — тип для операцій, які взаємодіють із зовнішнім світом.&lt;br /&gt;
&lt;br /&gt;
Приклад:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
main :: IO ()&lt;br /&gt;
main = putStrLn &amp;quot;Hello, Haskell&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
IO потрібен для:&lt;br /&gt;
&lt;br /&gt;
* читання файлів;&lt;br /&gt;
* запису файлів;&lt;br /&gt;
* network;&lt;br /&gt;
* database;&lt;br /&gt;
* console;&lt;br /&gt;
* random;&lt;br /&gt;
* time;&lt;br /&gt;
* взаємодії з OS.&lt;br /&gt;
&lt;br /&gt;
Haskell не забороняє side effects. Він робить їх явними у типах.&lt;br /&gt;
&lt;br /&gt;
== do notation ==&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;do notation&amp;#039;&amp;#039;&amp;#039; — синтаксис для послідовних monadic operations.&lt;br /&gt;
&lt;br /&gt;
Приклад:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
main :: IO ()&lt;br /&gt;
main = do&lt;br /&gt;
  putStrLn &amp;quot;What is your name?&amp;quot;&lt;br /&gt;
  name &amp;lt;- getLine&lt;br /&gt;
  putStrLn (&amp;quot;Hello, &amp;quot; ++ name)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Це схоже на імперативний код, але типи все одно контролюють effects.&lt;br /&gt;
&lt;br /&gt;
== Higher-order functions ==&lt;br /&gt;
&lt;br /&gt;
Haskell активно використовує functions як values.&lt;br /&gt;
&lt;br /&gt;
Приклади:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
map (*2) [1,2,3]&lt;br /&gt;
filter even [1..10]&lt;br /&gt;
foldr (+) 0 [1,2,3]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Higher-order functions дозволяють будувати дуже компактні transformations.&lt;br /&gt;
&lt;br /&gt;
== Function composition ==&lt;br /&gt;
&lt;br /&gt;
Композиція функцій записується через &amp;lt;code&amp;gt;.&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Приклад:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
normalizeName :: String -&amp;gt; String&lt;br /&gt;
normalizeName = trim . toLower&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Це означає: спочатку &amp;lt;code&amp;gt;toLower&amp;lt;/code&amp;gt;, потім &amp;lt;code&amp;gt;trim&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Function composition — один із ключових стилів Haskell-коду.&lt;br /&gt;
&lt;br /&gt;
== Currying ==&lt;br /&gt;
&lt;br /&gt;
У Haskell функції технічно приймають один аргумент і можуть повертати функцію.&lt;br /&gt;
&lt;br /&gt;
Приклад:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
add :: Int -&amp;gt; Int -&amp;gt; Int&lt;br /&gt;
add a b = a + b&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Це можна читати як:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Int -&amp;gt; (Int -&amp;gt; Int)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Тому можна частково застосовувати функції:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
add10 = add 10&lt;br /&gt;
add10 5&lt;br /&gt;
-- 15&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Recursion ==&lt;br /&gt;
&lt;br /&gt;
У Haskell loops часто виражаються через recursion або higher-order functions.&lt;br /&gt;
&lt;br /&gt;
Приклад:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sumList :: [Int] -&amp;gt; Int&lt;br /&gt;
sumList [] = 0&lt;br /&gt;
sumList (x:xs) = x + sumList xs&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
У production-коді часто використовують готові functions на кшталт &amp;lt;code&amp;gt;sum&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;map&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;fold&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Lists ==&lt;br /&gt;
&lt;br /&gt;
List — базова структура даних.&lt;br /&gt;
&lt;br /&gt;
Приклад:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
numbers :: [Int]&lt;br /&gt;
numbers = [1,2,3,4]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Операції:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
head numbers&lt;br /&gt;
tail numbers&lt;br /&gt;
map (*2) numbers&lt;br /&gt;
filter even numbers&lt;/div&gt;</summary>
		<author><name>R</name></author>
	</entry>
</feed>