2010-12-11 4 views
20

J'essaie d'ajouter une déclaration d'instance dans Haskell pour un nouveau type de données que j'ai créé sans succès. Voici ce que j'ai essayé jusqu'à présent:Haskell: déclaration de nouvelle instance pour Show

data Prediction = Prediction Int Int Int 
showPrediction :: Prediction -> String 
showPrediction (Prediction a b c) = show a ++ "-" ++ show b ++ "-" ++ show c 
instance Show (Prediction p) => showPrediction p 

Semble la dernière ligne est fausse mais je ne suis pas sûr de savoir comment réaliser ce que je veux. Fondamentalement, il est possible d'appeler une variable de prédiction à partir de l'interpréteur et de la visualiser sans avoir à appeler le showPrediction. En ce moment, cela fonctionne:

showPrediction (Prediction 1 2 3) 

et montre:

"1-2-3" 

comme prévu, mais je voudrais que cela fonctionne (de l'interprète):

Prediction 1 2 3 

Toutes les idées?

Répondre

44

Pour calculer une instance, la syntaxe est

instance «preconditions» => Class «type» where 
    «method» = «definition» 

Donc ici, par exemple, vous auriez

instance Show Prediction where 
    show (Prediction a b c) = show a ++ "-" ++ show b ++ "-" ++ show c 

Il n'y a pas de condition préalable; vous utiliseriez cela pour quelque chose comme instance Show a => Show [a] where ..., qui dit que sia est visible, alors il en est de même [a]. Ici, tous les Predictions sont affichés, donc il n'y a pas de quoi s'inquiéter. Lorsque vous avez écrit instance Show (Prediction p) => showPrediction p, vous avez fait quelques erreurs. Premièrement, Prediction p implique que Prediction est un type paramétré (un déclaré par, par exemple, data Prediction a = Prediction a a a), ce qui n'est pas le cas. Deuxièmement, Show (Prediction p) => implique que siPrediction P est affiché, puis vous souhaitez déclarer une autre instance. Et troisièmement, après le =>, avoir une fonction n'a pas de sens - Haskell voulait un nom de classe de type.

En outre, à cause de l'exhaustivité, il y a une autre façon de tirer Show si vous voulez le format Prediction 1 2 3 pour la sortie affichée:

data Prediction = Prediction Int Int Int deriving Show 

As specified in the Haskell 98 report, il y a seulement une poignée de types qui peuvent être dérivés de cette façon: EqOrd, Enum, Bounded, Show et Read.Avec the appropriate GHC extensions, vous pouvez également dériver Data, Typeable, Functor, Foldable et Traversable; vous pouvez dériver n'importe quelle classe qu'un type enveloppé de newtype a dérivé pour newtype; et vous pouvez générer ces instances automatiques de manière autonome.

+0

++ de haute qualité, approfondie, réponse complète. – delnan

+0

Merci pour la bonne réponse aussi! Le "Deriving Show" fonctionnait parfaitement aussi. Bon à savoir ;)) –

10

Vous avez la syntaxe pour les instances erronées. Pour créer une instance de Show écrire:

instance Show Foo where 
    show = ... 
    -- or 
    show x = ... 

... contient votre définition de la fonction show pour Foo.

Donc, dans ce cas, vous voulez:

instance Show Prediction where 
    show = showPrediction 

ou, car il n'y a pas une raison importante d'avoir showPrediction du tout:

instance Show Prediction where 
    show (Prediction a b c) = show a ++ "-" ++ show b ++ "-" ++ show c 
+0

Eh oui, ça y était. Merci beaucoup pour la réponse! :)) –

4

Remplacez votre dernière ligne avec:

instance Show Prediction where 
    show = showPrediction 
Questions connexes