haskell constructor ghc

haskell - Promoción de Data Constructor en GHC-7.6



(1)

Tenía este código:

class SymbolSet tpe where data Symbol tpe :: * data SSet tpe where Identity :: tpe -> SSet tpe And :: SSet tpe -> Symbol tpe -> SSet tpe class HasElem a b where instance (SymbolSet tpe) => HasElem (And (Identity tpe) s) s instance (HasElem sset s) => HasElem (And sset s) s

que estaba compilando en GHC-7.4. Sin embargo, al pasar a GHC-7.6 comenzó a dar errores de compilación:

''And'' of tpe `forall tpe. tpe -> Symbol * tpe -> SSet tpe'' is not promotable

Al profundizar en los documentos, encontré una nueva cláusula añadida a las páginas de "Promoción de tipos de datos" en GHC-7.6 frente a GHC-7.4

No promovemos los tipos de datos cuyos constructores son polimórficos amables, implican restricciones o utilizan la cuantificación existencial.

Mi pregunta es:

  1. ¿Cuál es la razón detrás de no promover tales constructores?
  2. ¿Cuál sería la forma correcta de hacerlo?

No dijiste qué versión de GHC 7.6 estabas usando ni qué extensiones tienes, así que supongo un poco.

Este boleto parece responder a su pregunta 1, aunque no entiendo totalmente el problema yo mismo. En su ejemplo particular, creo que SSet no es promocionable porque uno de sus argumentos ( Symbol tpe ) es un tipo asociado que trae consigo la restricción SymbolSet .

Si muevo Symbol fuera de la clase, obtenemos el tipo promocionado, sin embargo, ahora obtenemos errores de desajuste:

{-# LANGUAGE DataKinds , TypeFamilies , GADTs , MultiParamTypeClasses #-} class SymbolSet tpe where -- data Symbol tpe :: * data Symbol tpe :: * -- ...

Puedo obtener todo el shebang para compilar agregando firmas de tipo a HasElem :

{-# LANGUAGE DataKinds , TypeFamilies , GADTs , MultiParamTypeClasses, FlexibleInstances #-} class SymbolSet tpe where -- MOVED OUT OF CLASS: data Symbol tpe :: * data SSet tpe where Identity :: tpe -> SSet tpe And :: SSet tpe -> Symbol tpe -> SSet tpe -- ADDED KIND SIGNATURES: class HasElem (a :: SSet *) (b :: Symbol *) where instance (SymbolSet tpe) => HasElem (And (Identity tpe) s) s instance (HasElem sset s) => HasElem (And sset s) s

Realmente no entiendo tu código, así que puede que no funcione para ti.