Узагальнення - це можливість мови, яка дає змогу повторно використовувати код.
Наприклад, для обчислення довжини масиву не повинно мати значення, якого типу елементи він містить.
Саме тому функція length використовує узагальнений параметр типу a у своїй сигнатурі типу.
length : List a -> Int
Коли тип є узагальненим щодо іншого типу, ми використовуємо для цього іншого типу імʼя з маленької літери й називаємо його параметром типу.
Поширені приклади - це власні типи List, Maybe і Result.
-- Maybe is generic over the type a
type Maybe a
= Nothing
| Just a
someString : Maybe String
someString = Just "hello"
someInt : Maybe Int
someInt = Just 42
Одне важливе зауваження щодо назв параметрів типу: вони можуть складатися з кількох символів. Єдина умова - вони мають бути записані маленькими літерами. Тож коли це корисно, ми зазвичай даємо їм описові імена.
Тип може бути узагальненим щодо кількох інших типів і, отже, мати кілька параметрів типу. У такому разі кожен незалежний тип отримує інше імʼя з маленької літери. Незалежність не заважає їм стати одним і тим самим типом, вона лише дає їм змогу бути різними.
-- Result is generic over the types error and value
type Result error value
= Ok value
| Err error
Псевдоніми типів для записів теж можуть мати параметри типу, хоч це трапляється рідше.
-- Event is generic over the type a
type alias Event a =
{ at : Time
, data : a
}
Оскільки типи можуть бути узагальненими, то й функції можуть.
Можна писати функції, що працюють з узагальненими типами, як-от Maybe.withDefault.
withDefault : a -> Maybe a -> a
withDefault default maybe =
case maybe of
Just value -> value
Nothing -> default
Функції, які приймають інші функції як параметри, називають функціями вищого порядку, і вони теж можуть бути узагальненими.
map : (a -> b) -> Maybe a -> Maybe b
map function maybe =
case maybe of
Just value ->
Just (function value)
Nothing ->
Nothing
У цій вправі ми напишемо узагальнений (/ чарівний!) TreasureChest, щоб зберігати скарби.
Визначимо власний тип TreasureChest з одним варіантом.
Варіант має мати повʼязане значення String, у якому буде зберігатися пароль від скрині зі скарбами.
Варіант також має мати повʼязане узагальнене значення, у якому буде зберігатися скарб. Це значення узагальнене, тож скарбом може бути будь-що.
Ця функція має приймати два параметри
String (щоб спробувати пароль)TreasureChest
Функція має порівняти надану спробу пароля з String у TreasureChest.
Функція має повернути Maybe.
Якщо паролі збігаються, тоді повертаємо Just з узагальненим значенням із TreasureChest (зі скарбом!)
Якщо паролі не збігаються, тоді повертаємо Nothing.
Ця функція (вищого порядку) має приймати два параметри
TreasureChest з тим самим узагальненим типомФункція має викликати функцію-множник зі скарбом зі скрині.
Функція має повернути новий TreasureChest з тим самим паролем, що й початковий, і з помноженим скарбом (поверненим значенням)
Зареєструйтеся на Exercism, щоб вивчати й опановувати Elm, а також 28 концепцій110 вправ та справжнє наставництво від людей, і все це безкоштовно.