Problema al mezclar las clases de tipos y familias de tipo
-
25-09-2019 - |
Pregunta
Este código compila bien:
{-# LANGUAGE MultiParamTypeClasses, FunctionalDependencies, FlexibleInstances,
UndecidableInstances, FlexibleContexts, EmptyDataDecls, ScopedTypeVariables,
TypeOperators, TypeSynonymInstances, TypeFamilies #-}
class Sel a s b where
type Res a s b :: *
instance Sel a s b where
type Res a s b = (s -> (b,s))
instance Sel a s (b->(c,a)) where
type Res a s (b->(c,a)) = (b -> s -> (c,s))
pero tan pronto como añado el GHC R predicado falla:
{-# LANGUAGE MultiParamTypeClasses, FunctionalDependencies, FlexibleInstances,
UndecidableInstances, FlexibleContexts, EmptyDataDecls, ScopedTypeVariables,
TypeOperators, TypeSynonymInstances, TypeFamilies #-}
class Sel a s b where
type Res a s b :: *
instance Sel a s b where
type Res a s b = (s -> (b,s))
class R a where
type Rec a :: *
cons :: a -> Rec a
elim :: Rec a -> a
instance Sel a s (b->(c,Rec a)) where
type Res a s (b->(c,Rec a)) = (b -> s -> (c,s))
quejándose de que:
Illegal type synonym family application in instance:
b -> (c, Rec a)
In the instance declaration for `Sel a s (b -> (c, Rec a))'
¿qué significa y (más importante) cómo lo arreglo?
Gracias
Solución
Tipo familias son de un solo sentido: se puede ampliar Rec a
a su tipo computarizada, pero no se puede (única) pasar de la parte posterior expansión a Rec a
. Esto hace que las aplicaciones de funciones de tipo inadecuado para las firmas de instancia, ya que nunca pueden desencadenar la instancia de aplicar.
Se podría tratar en su lugar:
instance Rec a ~ reca => Sel a s (b->(c,reca))
Esto significa otra cosa: se dice que cualquier b -> (c, reca)
función es un ejemplo, y luego, cuando se ha emparejados de forma irrevocable, el compilador comprueba que Rec a ~ reca
. Pero esto podría ser lo suficientemente bueno para hacer falta en su caso.
Otros consejos
Rec
no es un constructor de tipos; que es una función de tipo. Tal vez se puede usar sólo en el tipo de un valor de tipo definición, no en una declaración de la clase? Supongo que aquí violentamente; No entiendo todas las reglas para familias tipo.
No sé cómo solucionarlo, pero algunas cosas para tratar de incluir:
-
Deshacerse de clase Sel y simplemente definir
type family Res a s b :: *
. Usotype instance
en lugar del mecanismo de clase. -
Es posible que apenas haciendo Tipo
Rec
inyectiva usandodata
va a ayudar, pero yo no lo creo. -
volver a la Corte el menor número de extensiones de lenguaje que podría, posiblemente, el trabajo que hará que sea más fácil para que otros le ayuden, y podría ayudar a que el compilador también.
Esto significa que usted no está permitido el uso de las familias synomym tipo cuando se declara instancias de tipo. Vea la sección "las familias de tipos y declaraciones de instancia" del manual GHC.
La única manera de solucionarlo es refactorizar el fin de no necesitarlo algún modo.