Question

Ce code compile 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))

mais dès que j'ajoute le GHC prédicat R échoue:

{-# 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))

se plaignant 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'est-ce que cela signifie et (surtout) comment puis-je résoudre ce problème?

Merci

Était-ce utile?

La solution

Type familles sont à sens unique: vous pouvez étendre Rec a à son type calculé, mais vous ne pouvez pas (uniquement) aller de l'expansion retour à Rec a. Cela rend les applications de fonctions de type ne convient pas pour les signatures d'exemple, car ils ne peuvent jamais déclencher l'instance d'appliquer.

Vous pouvez essayer à la place:

instance Rec a ~ reca => Sel a s (b->(c,reca))

Cela signifie quelque chose d'autre: il dit tout b -> (c, reca) de fonction est une instance, puis quand il a irrévocablement apparié, le compilateur vérifie que Rec a ~ reca. Mais cela pourrait être assez bon pour ne veulent dans votre cas.

Autres conseils

Rec est pas un constructeur de type; il est une fonction de type. Peut-être que vous pouvez l'utiliser que dans le type d'une valeur de définition de type, non pas dans une déclaration de classe? Je devine sauvagement ici; Je ne comprends pas toutes les règles pour les familles de type.

Je ne sais pas comment le résoudre, mais certaines choses à essayer les suivantes:

  • Débarrassez-vous de la classe Sel et définir simplement type family Res a s b :: *. Utilisez type instance à la place du mécanisme de la classe.

  • Il est à peine possible que faire Rec de type injective en utilisant data va aider, mais je ne pense pas.

  • Retour sur le plus petit nombre d'extensions de langage qui pourraient éventuellement travailler-il plus facile pour les autres de vous aider, et il pourrait aider le compilateur ainsi.

Cela signifie que vous n'êtes pas autorisé à utiliser les familles de type synomym lors de la déclaration des instances de type. Voir la section du manuel GHC "familles de type et d'instance déclarations".

La seule façon que vous pouvez le fixer est de factoriser afin de ne pas besoin d'une certaine manière.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top