Поиск…


Основное использование

Когда расширение GADTs включено, помимо регулярных объявлений данных, вы также можете объявить обобщенные алгебраические типы данных следующим образом:

data DataType a where
    Constr1 :: Int -> a -> Foo a -> DataType a
    Constr2 :: Show a => a -> DataType a
    Constr3 :: DataType Int

В объявлении GADT перечислены типы всех конструкторов, тип данных которых явно указан. В отличие от обычных деклараций типов данных тип конструктора может быть любой N-арной (включая нулевую) функцию, которая в конечном итоге приводит к типу данных, применяемому к некоторым аргументам.

В этом случае мы объявили, что тип DataType имеет три конструктора: Constr1 , Constr2 и Constr3 .

Конструктор Constr1 не отличается от объявленного с использованием регулярного объявления data DataType a = Constr1 Int a (Foo a) | ... : data DataType a = Constr1 Int a (Foo a) | ...

Однако Constr2 требует, чтобы a имел экземпляр Show , и поэтому при использовании конструктора экземпляр должен существовать. С другой стороны, при сопоставлении шаблонов на нем появляется тот факт, что a является экземпляром Show , поэтому вы можете написать:

foo :: DataType a -> String
foo val = case val of
    Constr2 x -> show x
    ...

Обратите внимание, что параметр Show a ограничение не отображается в типе функции и отображается только в коде справа от -> .

Constr3 имеет тип DataType Int , что означает, что всякий раз, когда значение типа DataType a является Constr3 , известно, что a ~ Int . Эта информация также может быть восстановлена ​​с совпадением шаблонов.



Modified text is an extract of the original Stack Overflow Documentation
Лицензировано согласно CC BY-SA 3.0
Не связан с Stack Overflow