2
votes

Please read my problem below, after the bold text, before taking your time to scrutinize this code. I don't want to waste your time if you can't answer this.

Okay. I have created my own data type within Haskell. It is

data Dialogue= Choice String [(String, Dialogue)] 
            | Action String Event
  -- deriving (Show)

Note the commented out 'deriving (Show)' which is important for my problem below.

I have a function named dialogue defined as

dialogue:: Game -> Dialogue -> IO Game
dialogue (Game n p ps) (Action s e) = do 
   putStrLn s
   return (e (Game n p ps))
dialogue (Game n p ps) (Choice s xs) = do
  putStrLn s
  let ys = [ fst a | a <- xs ]
  let i = [1..length ys]
  putStrLn (enumerate 1 ys)
  str <- getLine
  if str `elem` exitWords
  then do
     return (Game n p ps)
  else do
     let c = read str::Int
     if c `elem` i 
     then do 
        let ds = [ snd b | b <- xs ]
        let d = ds !! c
        putStrLn $ show d
        return (Game n p ps)
     else do
        error "error"

My data type game is defined as

data Game = Game Node Party [Party] | Won 
  deriving (Eq,Show)

And an Event is a type, defined by myself as

type Event = Game -> Game

Now, this is where my problem occurs. When I go to load this file within cmd and I have not included deriving (Show) within my data type Dialogue, I get the following error:

* No instance for (Show Dialogue) arising from a use of `show'
* In the second argument of `($)', namely `(show d)'
  In a stmt of a 'do' block: putStrLn $ (show d)
  In the expression:
    do let ds = ...
       let d = ds !! c
       putStrLn $ (show d)
       return (Game n p ps)
    |
120 |          putStrLn $ (show d)

It would seem to me that I need to include the deriving (Show) in order to be able to print this data type to the console. However, when I do include deriving (Show), I get this error:

* No instance for (Show Event)
    arising from the second field of `Action' (type `Event')
    (maybe you haven't applied a function to enough arguments?)
  Possible fix:
    use a standalone 'deriving instance' declaration,
      so you can specify the instance context yourself
* When deriving the instance for (Show Dialogue)
   |
85 |   deriving Show

I have spent quite a long time trying to find out why this might be happening. But I cannot find anywhere online that seems to document this particular problem.

Any help would be perfect, or even just a link to an appropriate explanation.

**Edit: ** My Event is a type synonym and so I cannot add deriving Show to this

Thanks a lot

2
Event has to have a Show instance for things containing it to be able to automatically derive Show. That probably means adding deriving Show to your Event definition.Ry-♦
His Event type is an alias and can not carry a deriving clause. It is also a function so automatic deriving won't work.Thomas M. DuBuisson
How would you expect to print an Event? Functions can not be printed in general. Perhaps you could define your own custom instance Show Dialogue without relying on Show Event, e.g. by showing that as some generic string "<event>".chi

2 Answers

4
votes

Event as you have defined it is a function which has no sensible method to show. How would you like to display this information? One solution is to import Text.Show.Functions, which has an instance.

For example:

Prelude Text.Show.Functions> show (+ 1)
"<function>"

Another solution is to define your own show instance:

instance Show (a -> b) where
    show _ = "_"
3
votes
type Event = Game -> Game
data Dialogue= Choice String [(String, Dialogue)] 
            | Action String Event
  -- deriving (Show)

When compiler tries to derive Show for Dialogue, it has to Show an Event in the Action variant, but it can't — Event is a function, and functions don't get auto-derived Show instances.

You have to manually implement either Show Event or Show Dialogue. One way to implement Show Dialogue would be this:

instance Show Dialogue where
    show (Choice s ds) = " "  `intercalate`  ["Choice", show s, show ds]
    show (Action s e) = " "  `intercalate`  ["Action", show s]