Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

New instance declaration for Show

Tags:

haskell

I'm trying to add an instance declaration in Haskell for a new data type I've created unsuccessfully. Here what I've tried so far:

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

Seems the last line is wrong but I'm not sure how to achieve what I want. Basically is to be able to call from the interpreter a Prediction variable and get it visualized without having to call the showPrediction. Right now this works:

showPrediction (Prediction 1 2 3)

and shows:

"1-2-3"

as expected, but I would like this to work (from the interpreter):

Prediction 1 2 3

Any ideas?

like image 800
Cristobal Viedma Avatar asked Dec 11 '10 17:12

Cristobal Viedma


2 Answers

To derive an instance, the syntax is

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

So here, for instance, you'd have

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

There's no precondition; you'd use that for something like instance Show a => Show [a] where ..., which says that if a is showable, then so is [a]. Here, all Predictions are showable, so there's nothing to worry about. When you wrote instance Show (Prediction p) => showPrediction p, you made a few mistakes. First, Prediction p implies that Prediction is a parametrized type (one declared by, for instance, data Prediction a = Prediction a a a), which it isn't. Second, Show (Prediction p) => implies that if Prediction P is showable, then you want to declare some other instance. And third, after the =>, having a function is nonsensical—Haskell wanted a type class name.

Also, for completeness's sake, there's another way to derive Show if you want the Prediction 1 2 3 format for displayed output:

data Prediction = Prediction Int Int Int deriving Show

As specified in the Haskell 98 report, there are only a handful of types which can be derived this way: Eq, Ord, Enum, Bounded, Show, and Read. With the appropriate GHC extensions, you can also derive Data, Typeable, Functor, Foldable, and Traversable; you can derive any class which a newtype's wrapped type derived for a newtype; and you can generate these automatic instances in a standalone way.

like image 119
Antal Spector-Zabusky Avatar answered Nov 10 '22 21:11

Antal Spector-Zabusky


You've got the syntax for instances wrong. To create an instance of Show write:

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

where ... contains your definition of the show function for Foo.

So in this case you want:

instance Show Prediction where
  show = showPrediction

or, since there isn't an important reason to have showPrediction at all:

instance Show Prediction where
  show (Prediction a b c) = show a ++ "-" ++ show b ++ "-" ++ show c
like image 19
sepp2k Avatar answered Nov 10 '22 20:11

sepp2k