Вы должны использовать умный конструктор.Вы реализуете свои ограничения, контролируя то, что вы экспортируете из модуля.
module Bounded exposing (Bounded, fromInt, toInt)
type Bounded
= Bounded Int
fromInt : Int -> Maybe Bounded
fromInt n =
if n < 0 || n > 29 then
Nothing
else
Just (Bounded n)
toInt : Bounded -> Int
toInt (Bounded n) = n
Объяснение
Тип Bounded
определяется как тип объединения с одним конструктором данных.При экспорте типа мы не экспортируем конструктор, то есть он не является частью общедоступного API.Это известно как непрозрачный тип .
Пользователи модуля могут создавать типы Bounded
только с использованием fromInt
.fromInt
называется умным конструктором , потому что он имеет некоторую логику ( смарт ) для обеспечения соблюдения ограничений.
Если вам нужно работать с целым числом, оно переноситсяВы используете toInt
.toInt
гарантированно всегда возвращает целое число от 0 до 29 включительно.Нет скрытого бэкдора, который позволил бы обернуть любое другое целое число.
На HaskellWiki есть хорошая статья о умных конструкторах .
Наконец, Ричард Фельдман в своем выступлении"Типы и тесты в позолоченной розе" приведен хороший пример здесь , который точно объясняет, что вы хотите сделать.