Какова цель экземпляра "Typeable (* → Constraint) Monoid"?

Так как GHC 7.8, Typeable является полиподобным. Глядя на список встроенных Typeable экземпляров в документации, я заметил что-то интересное:

Typeable ((* -> *) -> Constraint) Alternative
Typeable ((* -> *) -> Constraint) Applicative
Typeable (* -> Constraint) Monoid

По-видимому, это позволило посмотреть на представления типов (определенных) типов вида Constraint:

Prelude Data.Monoid Data.Typeable> typeRep $ (Proxy :: Proxy (Monoid Int))
Monoid Int

Используются ли какие-либо функции для этой функции или были ли они просто доступны случайно?

Ответ 1

Ну, теперь ConstraintKind разрешено. Таким образом, это означает, что вы можете определить типы данных, параметризованные по ограничениям.

A (надуманный) пример:

data CPair (c :: * -> Constraint) where
  MkCPair :: (c a, c b) => a -> b -> CPair c

Это пара двух компонентов потенциально разных типов, которые имеют общий класс:

aPair :: CPair Show
aPair = MkCPair 'x' True

Теперь, хотим ли мы aPair быть Typeable? Для этого требуется как CPair, так и Show be Typeable.

deriving instance Typeable CPair
deriving instance Typeable Show

Сейчас:

GHCi> typeOf aPair
CPair Show

Таким образом, это только приводит к выводу Typeable для классов, если они могут теперь отображаться как типы.

Самое смешное, что Typeable Show не является предопределенным, но Typeable Applicative is. Это связано с тем, что существует новое расширение GHC AutoDeriveTypeable, которое, как представляется, включено в некоторых модулях, но не в других. С AutoDeriveTypeable существуют экземпляры Typeable, которые выводятся для всего в модуле, включая классы.