Перейти до вмісту

Haskell

Матеріал з K2 ERP Wiki
Версія від 20:29, 8 травня 2026, створена R (обговорення | внесок) (Створена сторінка: {{SEO|title=Haskell — функціональна мова програмування, чисті функції, типи, монади, lazy evaluation, GHC, Cabal, Stack і безпечна архітектура|description=Haskell — Wiki-стаття про чисту функціональну мову програмування Haskell. Розглянуто pure functions, immutability, lazy evaluation, referential transparency, algebraic data ty...)
(різн.) ← Попередня версія | Поточна версія (різн.) | Новіша версія → (різн.)

Приклад:

Sum types дозволяють моделювати бізнес-логіку без неявних null або magic strings.;


Guards дозволяють писати умовну логіку.; Приклад:
List — базова структура даних.; Haskell має сильну статичну типізацію.; stack new my-project

'''Без містики:''' монада — це не “магія”.; Приклад:

* уникати випадкової зміни стану;
* спрощувати reasoning;
* краще працювати з concurrency;
* зменшувати кількість bugs.; * GHC;
* cabal-install;
* Stack;
* Haskell Language Server.; double :: Num a => a -> a

sumList [] = 0

Базові type classes:

  • ловити помилки під час компіляції;
  • документувати наміри;
  • моделювати domain;
  • забороняти неможливі стани;
  • робити refactoring безпечнішим.;

навчання функціональному мисленню забезпечується через Haskell часто використовують; додатково реалізовано компіляторів, формальних моделей, financial systems, backend-сервісів, DSL, research, high-assurance code, parserів, складної бізнес-логіки й задач, де типи можуть запобігти великій кількості помилок.;


== GHC ==

== Either ==

map (*2) numbers

Приклад:

 }
<pre>
Це можна читати як:

'''Haskell Language Server''' або '''HLS''' — language server для редакторів.; '''Monad''' — abstraction для послідовного поєднання обчислень у контексті.;== Monad ==

Prelude> map (*2) [1,2,3]


x = 10

== Currying ==

Якщо customer не знайдено, наступний крок не виконується.; '''GHCi''' — інтерактивне середовище Haskell.;<pre>

Але в production-коді часто корисно писати type signatures:

pure (+) <*> Just 2 <*> Just 3

Приклад: Ключова функція:

= Draft
== Типи ==

data Maybe a = Nothing | Just a

* навчання;
* швидкої перевірки functions;
* type exploration;
* debugging;
* prototyping;
* REPL workflow.; '''Strictness''' — протилежний підхід до lazy evaluation: значення обчислюється раніше.;<ref>https://www.haskell.org/ghc/</ref>

<div style="background:#eef6ff;border-left:6px solid #2f80ed;padding:14px 18px;margin:16px 0;border-radius:8px;">

<pre>

'''Pattern matching''' — спосіб розібрати значення за формою.; Для цього використовують:

Applicative — abstraction між Functor і Monad.;.; data PaymentResult

Haskell активно використовує functions як values.; Він робить їх явними у типах.;[1] Stack — альтернативний build tool для Haskell.; Haskell documentation page містить Cabal User Guide серед основних довідників Haskell tooling.; Pattern matching робить код дуже читабельним для обробки ADT.; Це схоже на креслення перед будівництвом, а не ремонт під час руху.; Через lazy evaluation Haskell має змогу створювати thunks замість негайного обчислення значень.;[2]

ADT допомагають явно описувати domain states.;== Referential transparency == add :: Int -> Int -> Int stack build

Приклад:

Він дає: Проста аналогія: Haskell змушує спочатку чітко описати “які значення можливі”, а вже потім писати код.; Приклад:

add 2 3 Product type містить кілька полів.; GHC охоплює:

Hackage

add10 5

putStrLn "What is your name?"

Актуальний стан інструментів

  • автодоповнення;
  • diagnostics;
  • go to definition;
  • hover info;
  • code actions;
  • formatting;
  • type information;
  • інтеграцію з VS Code.; Це binding імені x до значення 10.; numbers = [1,2,3,4]

stack test

IO Monad

'''Type class''' — механізм ad-hoc polymorphism.; add10 = add 10

Ключова ідея: результат одного кроку впливає на наступний крок.; Беруться лише перші 5 елементів.;


== Stack ==

class Printable a where

У Haskell іноді потрібно явно керувати strictness, щоб уникнути:

== Thunk ==

* пошуку libraries;
* перегляду package documentation;
* version history;
* dependencies;
* maintainers;
* source tarballs.; cabal test

Haskell не забороняє side effects.; * значення immutable;

  • функції не змінюють світ без явного типу;
  • типи описують можливі стани;
  • багато помилок ловить компілятор;
  • програма будується через композицію функцій.; do notation — синтаксис для послідовних monadic operations.; Операції:

main = putStrLn "Hello, Haskell"

Cabal

, customerName :: String

Haskell Language Server releases підтримують конкретні версії GHC, з цієї причини сумісність HLS і GHC потрібно перевіряти.; GHC сам виведе тип.; Компілятор змушує вас обробити випадок, коли значення немає.;

Ідея Stackage — мати набір package versions, які разом проходять build.;== Type classes ==
== GHCup ==
<pre>

Приклад:

Це означає: статус замовлення має змогу бути тільки Draft, Paid або Cancelled.;<pre>
filter even [1..10]
<div style="background:#fff7e6;border-left:6px solid #f2994a;padding:14px 18px;margin:16px 0;border-radius:8px;">

'''Lazy evaluation''' означає, що вирази обчислюються не одразу, а коли результат справді потрібен.; Приклад:
[2,4,6]
== Maybe ==

== Pattern matching ==

Type signatures документують код і допомагають ловити помилки раніше.;<div style="background:#eef6ff;border-left:6px solid #2f80ed;padding:14px 18px;margin:16px 0;border-radius:8px;">

count = 10

add a b = a + b
 printValue customer = customerName customer
</div>

Guards часто роблять код чистішим, ніж nested if.;<ref>https://docs.haskellstack.org/en/stable/</ref>

Це не змінна у звичному імперативному сенсі.;<pre>

'''Stackage''' — curated package set для Haskell.;</div>

Приклад:

'''Either''' часто застосовують, коли потрібно для результату з помилкою.; Either корисний для validation, parsing, API responses і business rules.; stack run

GHCi корисний для:

fmap (+1) (Just 10)
== Type inference ==
== Головна ідея ==

Приклад із Maybe:

<pre>
statusText :: OrderStatus -> String
5

Приклад:

Приклад:

main = do

<pre>

Higher-order functions дозволяють будувати дуже компактні transformations.;

statusText Paid = "Оплачено"

Guards

statusText Draft = "Чернетка"

map (*2) [1,2,3]

Immutability

Haskell має потужний type inference.;

як ілюстрація, Stackage Nightly 2026-05-06 використовував GHC 9.12.4.; deriving (Eq, Show)

Приклад ідеї:

name <- getLine
putStrLn ("Hello, " ++ name)

cabal run

printValue :: a -> String

це чиста функціональна мова програмування зі статичною типізацією, lazy evaluation, immutable data, algebraic data types, pattern matching, type classes і сильним акцентом на математичну коректність програм виступає ключовою рисою Haskell.;[3]

Stackage має:

tail numbers

GHCup — рекомендований installer і manager для Haskell toolchain.; Композиція функцій записується через .;

Це означає:

Lazy evaluation

Офіційна сторінка GHC описує його як state-of-the-art open source compiler and interactive environment for Haskell.; * читання файлів;

  • запису файлів;
  • network;
  • database;
  • console;
  • random;
  • time;
  • взаємодії з OS.;
<pre> instance Printable Customer where == Recursion == Там публікуються libraries і tools.; '''Hackage''' — центральний repository Haskell packages.; Тип має змогу мати instance: <pre> add :: Int -> Int -> Int як ілюстрація: == Applicative == Type classes схожі на interfaces, але мають іншу семантику й велику роль у Haskell ecosystem.; Function composition — один із ключових стилів Haskell-коду.;<ref>https://www.haskell.org/ghc/blog/20250702-ghc-release-schedules.html</ref> foldr (+) 0 [1,2,3] <pre> normalizeName = trim .; У Haskell це функціонує: нескінченний список <code>[1..]</code> не обчислюється в цілому.;== Eq, Ord, Show, Read == '''Cabal''' — build system і package description format для Haskell.;<ref>https://www.haskell.org/documentation/</ref> == Lists == | Paid | Cancelled Це корисно для laziness, але якщо thunks накопичуються, має змогу зрости використання пам’яті.; | PaymentDeclined String | PaymentError String </div> <pre> У Haskell значення immutable за замовчуванням.;<ref>https://www.haskell.org/downloads/</ref> <pre>

IO потрібен для:

statusText Cancelled = "Скасовано"

<pre>

 = PaymentOk
'''Цікаво:''' lazy evaluation надає можливість працювати з потенційно нескінченними структурами.; можна замінити на:

discount :: Int -> Int

Algebraic Data Types або ADT — один із найсильніших інструментів Haskell.;
  • bang patterns;
  • seq;
  • strict data fields;
  • strict libraries;
  • profiling.;

Приклад:

numbers :: [Int]

  • опису packages;
  • builds;
  • dependencies;
  • tests;
  • benchmarks;
  • library/executable targets;
  • Hackage packages.; Офіційна сторінка Haskell описує мову як purely functional programming language із referential transparency, immutability і lazy evaluation.;== Functor ==
Stack фокусується на reproducible builds і curated package sets через Stackage.;

Це означає: спочатку toLower, потім trim.; Це схоже на імперативний код, але типи все одно контролюють effects.; findCustomer customerId >>= findPrimaryEmail

deriving автономно створює instances.; 5

Hackage корисний для:

Int -> (Int -> Int)

Чиста функція — функція, яка: Referential transparency означає, що expression можна замінити його значенням без зміни поведінки програми.; IO — тип для операцій, які взаємодіють із зовнішнім світом.; take 5 [1..]

з цієї причини можна частково застосовувати функції:

  • Right Int — успішний результат;
  • Left String — помилка.;== do notation ==
Вона надає можливість застосовувати function у контексті до value у контексті.;<pre>

Офіційна сторінка Haskell називає referential transparency однією з ключових властивостей мови.; Через GHCup можна встановлювати:

Приклад:

У Haskell функції технічно приймають один аргумент і можуть повертати функцію.; -- Just 5

Ця функція чиста: вона лише обчислює суму.; | amount > 10000 = 20
 | amount > 5000 = 10
 | otherwise = 0
cabal update

data OrderStatus

name :: String

parseAmount :: String -> Either String Int

== Product types і sum types ==

</div>
'''Maybe''' — тип для значення, яке має змогу бути відсутнім.; { customerId :: Int
findCustomer :: Int -> Maybe Customer
== Чиста функція ==
== Function composition ==
-- 15

Приклад:

sumList :: [Int] -> Int

GHCi

Перед використанням package варто перевіряти maintenance, compatibility, license і recent releases.; * compiler;

  • runtime system;
  • GHCi;
  • optimizer;
  • extensions;
  • profiling support;
  • documentation;
  • libraries;
  • package support.; Приклад:
Functor — type class для контейнерів або контекстів, над якими можна застосувати функцію.;

Приклад: count :: Int


Це означає: customer має змогу бути знайдений або ні.; Окремо варто відзначити Vim, Emacs і іншими редакторами.; Різні версії compiler і dependencies можуть суттєво впливати на build.;<ref>https://www.haskell.org/downloads/</ref>

У Haskell підхід інший:

double x = x * 2

Приклад:

У production-коді часто використовують готові functions на кшталт <code>sum</code>, <code>map</code>, <code>fold</code>.; data Customer = Customer

  • LTS snapshots;
  • nightly snapshots;
  • GHC version binding;
  • curated ecosystem.;

{{SEO


Algebraic Data Types

Можна написати:

Приклади:
== Haskell Language Server ==
Functor надає можливість працювати з “значенням у контексті”, не витягуючи його вручну.; Документація Stack описує, що Stack керує GHC installations і автономно вибирає потрібну версію GHC для проєкту.; * змінні перезаписуються;
* об’єкти мутують;
* функції можуть змінювати глобальні інформаційні дані;
* side effects приховані;
* порядок виконання дуже важливий.;<pre>
name = "Haskell"
double x = x * 2

'''Thunk''' — відкладене обчислення.; ghci

<pre>
Cabal застосовується для:
normalizeName :: String -> String
Типові команди:
Типові команди:
Приклад:

У Haskell loops часто виражаються через recursion або higher-order functions.; Це спосіб акуратно з’єднувати обчислення, які мають контекст: Maybe, Either, IO, список, state, parser тощо.; Це сприяє зменшити dependency conflicts.;[4] Приклад:

<pre>
Офіційна сторінка Haskell Downloads рекомендує встановлювати Haskell через '''GHCup''', який має змогу встановити GHC, cabal-install, Stack і Haskell Language Server.;<pre>

-- Just 11

Головна ідея Haskell — будувати програми як композицію чистих функцій і точно описаних типів.; Вона вимагає іншого мислення, але користувачі можуть писати дуже передбачуваний код.; main :: IO ()

'''Практична користь:''' замість null Haskell використовує тип <code>Maybe</code>.; * <code>Eq</code> — порівняння на рівність;
* <code>Ord</code> — порядок;
* <code>Show</code> — перетворення в рядок;
* <code>Read</code> — читання з рядка.; add a b = a + b

* memory leaks;
* накопичення thunks;
* неочікуваного використання пам’яті;
* performance problems.; Але вона додатково має змогу створювати performance surprises, якщо не розуміти, коли саме обчислюються значення.; Applicative часто використовують у validation, parsing і configuration.; fmap :: Functor f => (a -> b) -> f a -> f b

завдяки наявності '''Коротко:''' Haskell — це мова, де функції чисті, інформаційні дані immutable, типи дуже сильні, а side effects явно контролюються.; toLower

Sum type описує вибір між варіантами.; discount amount

  • для однакових inputs завжди повертає однаковий output;
  • не змінює зовнішній стан;
  • не має прихованих side effects.; GHC або Glasgow Haskell Compiler — центральний компілятор Haskell.;

Приклад:

sumList (x:xs) = x + sumList xs

GHC додатково запровадив LTS-підхід: Haskell.org повідомляв, що GHC починає підтримувати LTS release/branch із довшим періодом підтримки, орієнтовно від двох до трьох років.; У звичайному імперативному стилі програма часто змінює стан:

data Status = Draft | Paid
Immutability сприяє:

== Strictness ==


filter even numbers

Prelude> 2 + 3 cabal build main :: IO () Станом на травень 2026 року офіційна сторінка GHC показує серед останніх релізів GHC 9.12.4 від 27 березня 2026 року і GHC 9.14.1 від 19 грудня 2025 року.; Практичне використання:

Stackage

Типи допомагають:

Це робить код передбачуванішим і полегшує reasoning.; Офіційна сторінка Haskell Downloads прямо рекомендує GHCup для Linux, macOS, FreeBSD, Windows або WSL2.;

head numbers

Higher-order functions

GHC є собою фактичним стандартом для сучасного Haskell.;

Для документації: у Haskell-проєктах істотно фіксувати версії GHC, Cabal/Stack і package set.; [5]