2011-11-13 8 views
6

En Associated Type Synonyms (Chakravarty, Keller, Jones) el papel parece indicar que lo siguiente es válido:¿Es posible tener un sinónimo de tipo asociado con variables no mencionadas en la clase de tipo?

class C a where 
    type S a (k :: * -> *) :: * 

Sin embargo, cuando intento ejecutar este recibo un error del compilador (con -XTypeFamilies):

Not in scope: type variable `k' 

¿Me falta algo, o la implementación real en GHC no es la misma que se menciona en el documento?

+0

Ahora he encontrado http://hackage.haskell.org/trac/ghc/ticket/3714 que para mí dice que esto no se puede hacer. Si esto es correcto, no dude en responder con eso. – ocharles

Respuesta

4

Como ya se enteraron, this is not possible in GHC:

Exactamente como en el caso de una declaración de datos asociada, los parámetros de tipo con nombre debe ser una permutación de un subconjunto de los parámetros de clase. Ejemplos

class C a b c where { type T c a :: * } -- OK 
class D a where { type T a x :: * }  -- No: x is not a class parameter 
class D a where { type T a :: * -> * } -- OK 

El billete se ha referido al hecho explica la razón de no poder definir algo como S. Funciona si lo haces así:

class C a where 
    type S a :: (* -> *) -> * 
data TupK a k = TupK (a, k a) 
instance C [a] where 
    type S [a] = TupK a 

Sin embargo, ahora estás atrapado con un nuevo tipo de datos. El uso de sinónimos tipo no funcionará ("Tipo sinónimo 'TupK' debe tener 2 argumentos"), y agregar más parámetros a S no ayudará ("El número de parámetros debe coincidir con la declaración familiar; esperado 1"), como se documenta en boleto.

+0

Bummer, pero gracias por la respuesta detallada! – ocharles

+1

@ocharles Agregaría que no * tiene * para usar un tipo * asociado *. Podrías perfectamente hacer algo como 'type family S a (k :: * -> *); clase C a donde foo :: S a [] -> Int'. La principal ventaja de los tipos asociados es que hace que sea más fácil para el compilador dar buenos mensajes de error (y una sintaxis más conveniente para declarar instancias de tipo). –

+0

Sí, por ahora he separado el 2, pero fue bueno tenerlos emparejados – ocharles

1

No, pero se puede hacer a los menos poderosos:

class C a where 
    type S a :: (k :: * -> *) -> * 

... que podría servir para el mismo propósito, si usted no necesita la potencia adicional.

Cuestiones relacionadas