Мы в основном используем данные для хранения значений, например:Как быстро сопоставляется шаблон Haskell?
data Sex = Male | Female
data Person = Person {name :: String, age :: Int, sex :: Sex}
charlie :: Person
charlie = Person "Charlie" 32 Male
И теперь у нас есть хорошие функции name
age
и sex
, чтобы получить значение данных с.
Но, с GADTs и Rank2, мы можем сделать что-то прохладнее:
{-# LANGUAGE GADTs #-}
{-# LANGUAGE Rank2Types #-}
data Sex = Male | Female
data Data a where
Name :: Data String
Age :: Data Int
Sex :: Data Sex
type Person = forall a. Data a -> a
charlie :: Person
charlie Name = "Charlie"
charlie Age = 32
charlie Sex = Male
Итак, это чертовски удивительным. Это дает нам великолепный синтаксис для определения людей и делает использование GADT гладким.
Но разве это действительно лучше? Как это отображается во время выполнения? Является ли сопоставление шаблонов на самом деле медленнее и/или больше в представлении, чем данные?
lt; dr: Как быстро сопоставляется образец по сравнению с поиском данных?
Я думаю, YMMV о том, является ли это полезным использованием GADT. Тем не менее, совпадение шаблонов - это самая быстрая вещь: все остальное зависит от нее (за исключением таких вещей, как математика с плавающей запятой). Что касается «поиска данных» (полевые помощники), вы можете посмотреть на ядро, чтобы увидеть, что они на самом деле делают. –
Попробуй и посмотри! Но я бы предсказал примерно на порядок замедление по сравнению с использованием данных. Но это связано скорее с накладными расходами на вызов неизвестной функции, чем из-за соответствия шаблонов. Версия функции также не совсем то же самое, потому что если поля являются более сложными выражениями, чем просто '32', они будут пересматриваться каждый раз. (Или вы или компилятор выталкиваете его из функции в закрытие, а затем просто заново изобретаете хранение данных в виде данных с дополнительными служебными данными для доступа к нему.) –
Проблема с представлением '(->) состоит в том, что обновление полей пространство утечек и поиск замедляются после каждого обновления. –