Question

J'ai besoin d'aide pour déterminer une erreur de compilation qui est vraiment me rend dingue ...

J'ai la classe de type:

infixl 7 -->
class Selectable a s b where
  type Res a s b :: *
  (-->) :: (CNum n) => (Reference s a) -> (n,(a->b),(a->b->a)) -> Res a s b

que je par exemple deux fois. La première fois va comme un charme:

instance Selectable a s b where
  type Res a s b = Reference s b
  (-->) (Reference get set) (_,read,write) = 
        (Reference (\s -> 
                      let (v,s') = get s
                      in (read v,s'))
                   (\s -> \x ->
                      let (v,s') = get s
                          v' = write v x
                          (_,s'') = set s' v'
                      in (x,s'')))   

car le type infère vérificateur

(-->) :: Reference s a -> (n,a->b,a->b->a) -> Reference s b

et cette signature correspond à la signature de classe (->) depuis

Res a s b = Reference s b

Maintenant, j'ajouter une seconde instance et tout pauses:

instance (Recursive a, Rec a ~ reca) => Selectable a s (Method reca b c) where
  type Res a s (Method reca b c) = b -> Reference s c
  (-->) (Reference get set) (_,read,write) =
    \(x :: b) -> 
        from_constant( Constant(\(s :: s)->
                          let (v,s') = get s :: (a,s)
                              m = read v
                              ry = m x :: Reference (reca) c
                              (y,v') = getter ry (cons v) :: (c,reca)
                              v'' = elim v'
                              (_,s'') = set s' v''
                              in (y,s''))) :: Reference s c

le compilateur se plaint que

Couldn't match expected type `Res a s (Method reca b c)'
       against inferred type `b -> Reference s c'
The lambda expression `\ (x :: b) -> ...' has one argument,
which does not match its type
In the expression:
    \ (x :: b)
        -> from_constant (Constant (\ (s :: s) -> let ... in ...)) ::
             Reference s c
In the definition of `-->':
    --> (Reference get set) (_, read, write)
          = \ (x :: b)
                -> from_constant (Constant (\ (s :: s) -> ...)) :: Reference s c

lire attentivement le compilateur me dit qu'il en a déduit le type de (->) ainsi:

(-->) :: Reference s a -> (n,a->(Method reca b c),a->(Method reca b c)->a) -> (b -> Reference s c)

qui est correct puisque

Res a s (Method reca b c) = b -> Reference s c

mais pourquoi ne peut-il correspondre aux deux définitions?

Désolé pour ne pas offrir un exemple plus succint et autonome, mais dans ce cas, je ne peux pas comprendre comment faire ça ...

Était-ce utile?

La solution

Lorsque vous écrivez

instance Selectable a s b where

vous dites que tout combinaison de types est une instance de sélectionnable. Cela ne laisse aucune place pour d'autres cas.

Bien sûr, certaines extensions ombragées du compilateur vous permettent d'écrire des instances plus (nécessairement contradictoires), mais vous êtes liés à des ennuis.

Pouvez-vous faire de votre première instance plus spécifique afin qu'il soit en contradiction ne sont plus avec l'autre instance que vous essayez d'écrire?

L'exécution des problèmes comme ceux-ci est généralement un signe que les classes de type ne sont pas la réponse. Si vous écrivez seulement deux cas, pourquoi ne pas renoncer à la surcharge et il suffit d'écrire deux fonctions spécifiques une pour chaque cas d'utilisation?

Autres conseils

Comme je l'ai dit ailleurs, je ne sais pas ce qui se passe en second lieu donné si peu de contexte. Cependant, peut-être que vous pouvez faire vos instances ne se chevauchent pas en faisant ceci:

class Selectable a s b r where
    (-->) :: (CNum n) => (Reference s a) -> (n,(a->b),(a->b->a)) -> r

instance Selectable a s b (Reference s b) where ...
instance (Recursive a, Rec a ~ reca) => Selectable a s (Method reca b c) (b -> Reference s c) where ...

Ceci est susceptible de vous causer des problèmes sur les sites d'appel au lieu, cependant, et il est probablement préférable d'utiliser deux fonctions avec des noms différents.

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