Алгебраїчний тип даних (АТД) представляє фіксовану кількість іменованих випадків. Кожне значення АТД відповідає рівно одному з цих іменованих випадків.
АТД визначають за допомогою ключового слова data, а випадки розділяють символом вертикальної риски (|).
Якщо з жодним із випадків не повʼязано даних, такий АТД схожий на те, що в інших мовах зазвичай називають переліком (або enum).
data Season
= Spring
| Summer
| Autumn
| Winter
Кожен випадок АТД може мати повʼязані з ним дані, а може й не мати; різні випадки можуть мати дані різних типів. Якщо з випадком повʼязані дані, потрібен конструктор.
data Number
= NInt Int --'NInt' is the constructor for an Int Number.
| NFloat Float --'NFloat' is the constructor for an Float Number.
| Invalid --'Invalid' does not have data associated to it.
Щоб створити значення для конкретного випадку, достатньо послатися на його назву (наприклад, NInt 22).
Оскільки назви випадків - це просто функції-конструктори, повʼязані дані можна передати як звичайний аргумент функції.
АТД мають структурну рівність: це означає, що два значення для одного й того самого випадку з однаковими (необовʼязковими) даними рівнозначні.
Хоч для роботи з АТД можна використовувати вирази if/else, рекомендовано працювати з ними через зіставлення зі зразком за допомогою інструкції case:
add1 :: Number -> String
add1 number =
case number of
NInt i -> show (i + 1)
NFloat f -> show (f + 1.0)
Invalid -> error "Invalid input"