Во-первых, вам не хватает части определения: самого объявления data family
.
data family HList (l :: [*])
data instance HList '[] = HNil
newtype instance HList (x ': xs) = HCons1 (x, HList xs)
Это называется data family
(доступно с расширением TypeFamilies
).
pattern HCons x xs = HCons1 (x, xs)
Это двунаправленный шаблон (доступен с расширением PatternSynonyms
).
Что такое синтаксис '[]
и (x ': xs)
, который я вижу?
Знак '
перед конструкторами означает их продвигаемые аналоги на уровне типа. Для синтаксического удобства продвинутые списки и кортежи также нуждаются в дополнительной галочке (и мы по-прежнему можем писать '[]
для пустого списка уровня типа и ':
для минусов уровня типа. Все это доступно через расширение DataKinds
.
Есть ли смысл использовать объявление newtype
с кортежем (вместо объявления данных с двумя полями), кроме как избегать упаковки HCons1
?
Да, чтобы убедиться, что HList
имеет репрезентативную роль, что означает вы можете указать между HList
s1. Это слишком сложно, чтобы объяснять просто ответом, но вот пример того, когда все идет не так, как мы хотим, когда у нас есть
data instance HList (x ': xs) = HCons x (HList xs)
вместо newtype instance
(и без шаблона). Рассмотрим следующие newtype
, которые репрезентативно эквивалентны Int
, Bool
и ()
соответственно.
newtype MyInt = MyInt Int
newtype MyBool = MyBool Bool
newtype MyUnit = MyUnit ()
Напомним, мы можем использовать coerce
для переноса или разворачивать эти типы автоматически. Ну, мы хотели бы иметь возможность делать то же самое, но в целом HList
:
ghci> l = (HCons 3 (HCons True (HCons () HNil))) :: HList '[Int, Bool, ()]
ghci> l' = coerce l :: HList '[MyInt, MyBool, MyUnit]
Это работает с вариантом newtype instance
, но не с data instance
из-за ролей. (Подробнее об этом здесь.)
1 технически, для data family
в целом нет роли: роли могут быть разными для каждого instance
/newtype
- здесь нам действительно нужен только случай HCons
, чтобы он был репрезентативным, так как именно он получает по принуждению. Проверьте этот билет Trac.
person
Alec
schedule
14.12.2016