Они эквивалентны:
newtype NT a b = MkNT (Int, b)
data family DF a b
newtype instance DF a b = MkDF (Int, b)
-- inferred MkNT :: (Int, b) -> NT a b
-- MkDF :: (Int, b) -> DF a b
Более того, вы не можете объявить любой другой экземпляр / конструктор в семействе DF
, потому что их заголовки экземпляра будут перекрываться DF a b
.
.сообщение об ошибке в q re standalone newtype Baz
вводит в заблуждение
-- Error: A newtype constructor must have a return type of form T a1 ... an
(и предположительно датируется тем, что появились семейства данных).Конструктор нового типа должен иметь возвращаемый тип в точности как заголовок экземпляра (переименование по модулю альфа, если он использует синтаксис GADT).Для автономного нового типа «заголовок экземпляра» означает заголовок newtype
.
Для экземпляров данных не нового типа различные конструкторы могут иметь типы возвращаемых данных, более специфичные, чем заголовок экземпляра (что делает их GADT).
Тип, объявленный в заголовке экземпляра data / newtype (в литературе по-разному называемый «схемой типа», «монотипом» - потому что нет ограничений, «Тип без функции» - в статье 2008 года »).Проверка типов с использованием открытых функций типов ') - это основной тип, с которым должны возвращаться все возвращаемые типы конструкторов.(Не может быть никаких конструкторов с точно таким возвращаемым типом.)
Если ваш экземпляр - newtype
, правила намного строже: может быть только один конструктор, и его тип возвращаемого значения должен быть точноосновной тип.Итак, чтобы ответить на исходный q
Означает ли это, что newtype
является свойством конструктора данных, а не типа данных?... но ... Тогда является ли newtype
свойством типа результата, а не конструктора?
Нет, не конструктора;да, больше похоже на результат: быть новым типом - это свойство экземпляра семейства данных / его основного типа.Просто для автономных новых типов может быть только один экземпляр, и его основной тип является наиболее общим типом для этого конструктора типов.Производно, мы можем сказать, что основной тип нового типа / тип возврата однозначно идентифицирует конструктор данных.Это важно для безопасности типов, потому что значения этого типа делят свое представление с типом внутри конструктора данных нового типа, то есть без обертки - как указывает комментарий @ AlexisKing.Тогда сопоставление с образцом не нужно искать в конструкторе: совпадение неопровержимо / конструктор является виртуальным.
Мне кажется, что в интересах более точного набора текста / лучшей документации, вы можете объявитьновый тип как семейство данных только с одним экземпляром, чья голова более конкретна, чем то, что вы должны указать для автономного нового типа.