2015-07-23 3 views
4

Vu le code suivant:Typeclasses 101: GHC trop "désireux" de dériver l'instance?

class C a where 
    foo :: a -> a 

f :: (C a) => a -> a 
f = id 

p :: (C a) => (a -> a) -> a -> a 
p g = foo . g 

Maintenant, si je tente d'invoquer pF, GHC se plaint:

> p f 
No instance for (C a0) arising from a use of `p' 
In the expression: p f 
In an equation for `it': it = p f 

Je trouve cela un peu surprenant, puisque f accepte seulement un "a" qui doit être une instance de la classe C. Quelle est la raison?

Edit: Je sais que je ne définissaient pas une instance C mais ne devrait pas la réponse « appropriée » être:

p f :: (C a) => a -> a 
+4

'p f :: (C a) => a -> est la réponse a' propre à': t p f', mais vous avez entré 'p f'. –

+0

La question que GHCi pose est, * "Je sais que c'est une instance de' C', mais de quelle instance s'agit-il? Sinon, je ne peux pas déterminer si je peux le 'montrer' ou non. "* – AJFarmar

Répondre

8

Lorsque vous mettez une expression ordinaire dans ghci , il essaie essentiellement de print, donc

> p f 

est approximatel y le même que celui ayant les éléments suivants dans un fichier

main :: IO() 
main = print $ p f 

Comme vous l'avez indiqué, p f :: (C a) => a -> a. Afin de print $ p f GHC doit évaluer p f. GHC ne peut pas évaluer une valeur avec un contexte de classe de type sans choisir un dictionnaire à transmettre. Pour ce faire, il doit trouver une instance C a pour tous les a, qui ne se termine pas. Il doit également trouver une instance Show pour a -> a. L'incapacité de trouver une ou l'autre de ces résultats dans deux erreurs

No instance for (Show (a -> a)) arising from a use of `print' 
No instance for (C a) arising from a use of `p' 
4

C'est la monomorphism restriction redoutée en action. Par défaut, GHC ne nous permet pas d'avoir des définitions de valeur de niveau supérieur sans annotations de type si le type inféré a une contrainte de classe. A) Suppression de la restriction en ajoutant {-# LANGUAGE NoMonomorphismRestriction #-} au début de votre source. Vous pouvez remédier à la situation par

a.

b) Ajout d'annotations de type de liaisons haut niveau concernés:..

foo :: C a => a -> a 
foo = p f 

c) Développer des définitions de fonction (si possible):

foo x = p f x 
+3

restriction de monomorphisme avec ': set -XNoMonomorphismRestriction' en entrant l'expression nue' pf' dans ghci entraîne l'erreur 'Aucune instance pour (C c0) ...'. – Cirdec

+1

Je pense que c'est un artefact découlant de GHCi-7.8 essayant de l'imprimer. GHCi-7.10 ne donne pas ce message d'erreur (à la place, il lance 'Aucune instance pour Show ...'). –

+8

Cela n'a rien à voir avec l'impression ('' p f 'seq'()' 'donne aussi une erreur), et ce n'est pas vraiment le MR non plus. C'est quelque chose de beaucoup plus fondamental: GHC ne peut * évaluer * une valeur avec un contexte de classe de type sans choisir un dictionnaire à transmettre. En particulier, peu importe comment vous le découpez, il ne sait pas * quel * type 'foo' utiliser ici. –