Непрозорі типи в Gleam - це власні типи, значення яких може створювати або зіставляти зі зразком лише модуль, що визначає цей тип. Це корисно, коли треба створити типи, які можна використовувати лише в певний спосіб.
Непрозорі типи визначають за допомогою ключового слова opaque.
pub opaque type PositiveInt {
PositiveInt(inner: Int)
}
Тип PositiveInt призначений для ситуацій, де потрібне ціле число, але воно має бути нулем або більшим. Звичайний Int у Gleam тут не підійде, бо він може бути й відʼємним.
Модуль, що визначає цей тип, може визначити функцію, яка повертає внутрішнє ціле число, і функцію для створення типу PositiveInt, яка поверне помилку, якщо значення не є додатним.
pub fn from_int(i: Int) -> Result(PositiveInt, String) {
case i {
_ if i < 0 -> Error("Value must be positive")
_ -> Ok(PositiveInt(i))
}
}
pub fn to_int(i: PositiveInt) -> Int {
i.inner
}
Із цим API інші модулі не можуть створити PositiveInt з відʼємним значенням, тож будь-яка функція, що приймає PositiveInt, може бути певна, що значення додатне.
Уважні учні помітили, що тип TreasureChest у попередній вправі не був таким уже й захищеним!
Якщо ми використовували функцію get_treasure, то мали надати пароль, але все ще могли деструктурувати тип TreasureChest, щоб отримати скарб, навіть не знаючи пароля.
Виправмо це, використавши непрозорий тип.
TreasureChest.TreasureChest містить два поля:
String.Тип TreasureChest має бути непрозорим.
create.Ця функція приймає два аргументи:
String.Функція повертає TreasureChest, що містить пароль і значення.
Якщо пароль коротший за 8 символів, тоді функція має повернути помилку з текстом Password must be at least 8 characters long.
open.Ця функція приймає два аргументи:
TreasureChest.String.Якщо пароль збігається з паролем у TreasureChest, тоді функція має повернути скарб, інакше вона має повернути помилку з текстом Incorrect password.
Зареєструйтеся на Exercism, щоб вивчати й опановувати Gleam, а також 33 концепції122 вправи та справжнє наставництво від людей, і все це безкоштовно.